blob: 592be1b1b51be08e7d3c8ea2bfbe8d2127bfbdf1 [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 Wallace5c7cf1c2017-10-24 04:12:18 -040025#include <vcl/vcom_socket_wrapper.h>
26#include <vcl/vcom.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;
52 char app_name[VCOM_APP_NAME_MAX];
53 u32 sid_bit_val;
54 u32 sid_bit_mask;
55 u32 debug;
56 u8 *io_buffer;
57 clib_time_t clib_time;
58 clib_bitmap_t *rd_bitmap;
59 clib_bitmap_t *wr_bitmap;
60 clib_bitmap_t *ex_bitmap;
61 clib_bitmap_t *sid_rd_bitmap;
62 clib_bitmap_t *sid_wr_bitmap;
63 clib_bitmap_t *sid_ex_bitmap;
64 clib_bitmap_t *libc_rd_bitmap;
65 clib_bitmap_t *libc_wr_bitmap;
66 clib_bitmap_t *libc_ex_bitmap;
67 vcl_poll_t *vcl_poll;
68 u8 select_vcl;
69 u8 epoll_wait_vcl;
70} vcom_main_t;
71#define VCOM_DEBUG vcom->debug
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070072
Dave Wallace048b1d62018-01-03 22:24:41 -050073static vcom_main_t vcom_main = {
74 .sid_bit_val = (1 << VCOM_SID_BIT_MIN),
75 .sid_bit_mask = (1 << VCOM_SID_BIT_MIN) - 1,
76 .debug = VCOM_DEBUG_INIT,
77};
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070078
Dave Wallace048b1d62018-01-03 22:24:41 -050079static vcom_main_t *vcom = &vcom_main;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070080
81/*
82 * RETURN: 0 on success or -1 on error.
83 * */
Dave Wallace048b1d62018-01-03 22:24:41 -050084static inline void
85vcom_set_app_name (char *app_name)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070086{
Dave Wallace048b1d62018-01-03 22:24:41 -050087 int rv = snprintf (vcom->app_name, VCOM_APP_NAME_MAX,
88 "vcom-%d-%s", getpid (), app_name);
89
90 if (rv >= VCOM_APP_NAME_MAX)
91 app_name[VCOM_APP_NAME_MAX - 1] = 0;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070092}
93
Dave Wallace048b1d62018-01-03 22:24:41 -050094static inline char *
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070095vcom_get_app_name ()
96{
Dave Wallace048b1d62018-01-03 22:24:41 -050097 if (vcom->app_name[0] == '\0')
98 vcom_set_app_name ("app");
99
100 return vcom->app_name;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700101}
102
Dave Wallace048b1d62018-01-03 22:24:41 -0500103static inline int
104vcom_fd_from_sid (u32 sid)
105{
106 if (PREDICT_FALSE (sid >= vcom->sid_bit_val))
107 return -EMFILE;
108 else
109 return (sid | vcom->sid_bit_val);
110}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700111
Dave Wallace048b1d62018-01-03 22:24:41 -0500112static inline int
113vcom_fd_is_sid (int fd)
114{
115 return ((u32) fd & vcom->sid_bit_val) ? 1 : 0;
116}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700117
Dave Wallace048b1d62018-01-03 22:24:41 -0500118static inline u32
119vcom_sid_from_fd (int fd)
120{
121 return (vcom_fd_is_sid (fd) ? ((u32) fd & vcom->sid_bit_mask) :
122 INVALID_SESSION_ID);
123}
124
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700125static inline int
Dave Wallace227867f2017-11-13 21:21:53 -0500126vcom_init (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700127{
Dave Wallace048b1d62018-01-03 22:24:41 -0500128 int rv = 0;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700129
Dave Wallace048b1d62018-01-03 22:24:41 -0500130 if (PREDICT_FALSE (!vcom->init))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700131 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500132 vcom->init = 1;
Dave Wallace4adccc92017-11-27 17:07:51 -0500133 rv = vppcom_app_create (vcom_get_app_name ());
Dave Wallace048b1d62018-01-03 22:24:41 -0500134 if (rv == VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700135 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500136 char *env_var_str = getenv (VCOM_ENV_DEBUG);
137 if (env_var_str)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700138 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500139 u32 tmp;
140 if (sscanf (env_var_str, "%u", &tmp) != 1)
141 clib_warning ("LDP<%d>: WARNING: Invalid VCOM debug level "
142 "specified in the env var " VCOM_ENV_DEBUG
143 " (%s)!", getpid (), env_var_str);
144 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700145 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500146 vcom->debug = tmp;
147 clib_warning ("LDP<%d>: configured VCOM debug level (%u) "
148 "from the env var " VCOM_ENV_DEBUG "!",
149 getpid (), vcom->debug);
150 }
151 }
152
153 env_var_str = getenv (VCOM_ENV_APP_NAME);
154 if (env_var_str)
155 {
156 vcom_set_app_name (env_var_str);
157 clib_warning ("LDP<%d>: configured VCOM app name (%s) "
158 "from the env var " VCOM_ENV_APP_NAME "!",
159 getpid (), vcom->app_name);
160 }
161
162 env_var_str = getenv (VCOM_ENV_SID_BIT);
163 if (env_var_str)
164 {
165 u32 sb;
166 if (sscanf (env_var_str, "%u", &sb) != 1)
167 {
168 clib_warning ("LDP<%d>: WARNING: Invalid VCOM sid bit "
169 "specified in the env var "
170 VCOM_ENV_SID_BIT " (%s)!"
171 "sid bit value %d (0x%x)",
172 getpid (), env_var_str,
173 vcom->sid_bit_val, vcom->sid_bit_val);
174 }
175 else if (sb < VCOM_SID_BIT_MIN)
176 {
177 vcom->sid_bit_val = (1 << VCOM_SID_BIT_MIN);
178 vcom->sid_bit_mask = vcom->sid_bit_val - 1;
179
180 clib_warning ("LDP<%d>: WARNING: VCOM sid bit (%u) "
181 "specified in the env var "
182 VCOM_ENV_SID_BIT " (%s) is too small. "
183 "Using VCOM_SID_BIT_MIN (%d)! "
184 "sid bit value %d (0x%x)",
185 getpid (), sb, env_var_str, VCOM_SID_BIT_MIN,
186 vcom->sid_bit_val, vcom->sid_bit_val);
187 }
188 else if (sb > VCOM_SID_BIT_MAX)
189 {
190 vcom->sid_bit_val = (1 << VCOM_SID_BIT_MAX);
191 vcom->sid_bit_mask = vcom->sid_bit_val - 1;
192
193 clib_warning ("LDP<%d>: WARNING: VCOM sid bit (%u) "
194 "specified in the env var "
195 VCOM_ENV_SID_BIT " (%s) is too big. "
196 "Using VCOM_SID_BIT_MAX (%d)! "
197 "sid bit value %d (0x%x)",
198 getpid (), sb, env_var_str, VCOM_SID_BIT_MAX,
199 vcom->sid_bit_val, vcom->sid_bit_val);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700200 }
201 else
202 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500203 vcom->sid_bit_val = (1 << sb);
204 vcom->sid_bit_mask = vcom->sid_bit_val - 1;
205
206 clib_warning ("LDP<%d>: configured VCOM sid bit (%u) "
207 "from " VCOM_ENV_SID_BIT
208 "! sid bit value %d (0x%x)", getpid (),
209 sb, vcom->sid_bit_val, vcom->sid_bit_val);
210 }
211 }
212
213 clib_time_init (&vcom->clib_time);
214 clib_warning ("LDP<%d>: VCOM initialization: done!", getpid ());
215 }
216 else
217 {
218 fprintf (stderr, "\nLDP<%d>: ERROR: vcom_init: vppcom_app_create()"
219 " failed! rv = %d (%s)\n",
220 getpid (), rv, vppcom_retval_str (rv));
221 vcom->init = 0;
222 }
223 }
224 return rv;
225}
226
227int
228close (int fd)
229{
230 int rv;
231 const char *func_str;
232 u32 sid = vcom_sid_from_fd (fd);
233
234 if ((errno = -vcom_init ()))
235 return -1;
236
237 if (sid != INVALID_SESSION_ID)
238 {
239 int epfd;
240
241 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
242 epfd = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
243 if (epfd > 0)
244 {
245 func_str = "libc_close";
246
247 if (VCOM_DEBUG > 0)
248 clib_warning
249 ("LDP<%d>: fd %d (0x%x): calling %s(): epfd %u (0x%x)",
250 getpid (), fd, fd, func_str, epfd, epfd);
251
252 rv = libc_close (epfd);
253 if (rv < 0)
254 {
255 u32 size = sizeof (epfd);
256 epfd = 0;
257
258 (void) vppcom_session_attr (sid, VPPCOM_ATTR_SET_LIBC_EPFD,
259 &epfd, &size);
260 }
261 }
262 else if (PREDICT_FALSE (epfd < 0))
263 {
264 errno = -epfd;
265 rv = -1;
266 goto done;
267 }
268
269 func_str = "vppcom_session_close";
270
271 if (VCOM_DEBUG > 0)
272 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
273 getpid (), fd, fd, func_str, sid, sid);
274
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
286 if (VCOM_DEBUG > 0)
287 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s()",
288 getpid (), fd, fd, func_str);
289
290 rv = libc_close (fd);
291 }
292
293done:
294 if (VCOM_DEBUG > 0)
295 {
296 if (rv < 0)
297 {
298 int errno_val = errno;
299 perror (func_str);
300 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
301 "rv %d, errno = %d", getpid (), fd, fd,
302 func_str, rv, errno_val);
303 errno = errno_val;
304 }
305 else
306 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
307 getpid (), fd, fd, rv, rv);
308 }
309 return rv;
310}
311
312ssize_t
313read (int fd, void *buf, size_t nbytes)
314{
315 ssize_t size;
316 const char *func_str;
317 u32 sid = vcom_sid_from_fd (fd);
318
319 if ((errno = -vcom_init ()))
320 return -1;
321
322 if (sid != INVALID_SESSION_ID)
323 {
324 func_str = "vppcom_session_read";
325
326 if (VCOM_DEBUG > 2)
327 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
328 "sid %u (0x%x), buf %p, nbytes %u", getpid (),
329 fd, fd, func_str, sid, sid, buf, nbytes);
330
331 size = vppcom_session_read (sid, buf, nbytes);
332 if (size < 0)
333 {
334 errno = -size;
335 size = -1;
336 }
337 }
338 else
339 {
340 func_str = "libc_read";
341
342 if (VCOM_DEBUG > 2)
343 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
344 "buf %p, nbytes %u", getpid (),
345 fd, fd, func_str, buf, nbytes);
346
347 size = libc_read (fd, buf, nbytes);
348 }
349
350 if (VCOM_DEBUG > 2)
351 {
352 if (size < 0)
353 {
354 int errno_val = errno;
355 perror (func_str);
356 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
357 "rv %d, errno = %d", getpid (), fd, fd,
358 func_str, size, errno_val);
359 errno = errno_val;
360 }
361 else
362 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
363 getpid (), fd, fd, size, size);
364 }
365 return size;
366}
367
368ssize_t
369readv (int fd, const struct iovec * iov, int iovcnt)
370{
371 const char *func_str;
372 ssize_t size = 0;
373 u32 sid = vcom_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -0500374 int rv = 0, i, total = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500375
376 if ((errno = -vcom_init ()))
377 return -1;
378
379 if (sid != INVALID_SESSION_ID)
380 {
381 func_str = "vppcom_session_read";
382 do
383 {
384 for (i = 0; i < iovcnt; ++i)
385 {
386 if (VCOM_DEBUG > 2)
387 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s() [%d]: "
388 "sid %u (0x%x), iov %p, iovcnt %d, total %d",
389 getpid (), fd, fd, func_str, i, sid, sid,
390 iov, iovcnt, total);
391
392 rv = vppcom_session_read (sid, iov[i].iov_base, iov[i].iov_len);
393 if (rv < 0)
394 break;
395 else
396 {
397 total += rv;
398 if (rv < iov[i].iov_len)
399 {
400 if (VCOM_DEBUG > 2)
401 clib_warning ("LDP<%d>: fd %d (0x%x): "
402 "rv (%d) < iov[%d].iov_len (%d)",
403 getpid (), fd, fd, rv, i,
404 iov[i].iov_len);
405 break;
406 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700407 }
408 }
409 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500410 while ((rv >= 0) && (total == 0));
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700411
Dave Wallace048b1d62018-01-03 22:24:41 -0500412 if (rv < 0)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700413 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500414 errno = -rv;
415 size = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700416 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500417 else
418 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700419 }
420 else
421 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500422 func_str = "libc_readv";
423
424 if (VCOM_DEBUG > 2)
425 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
426 "iov %p, iovcnt %d", getpid (), fd, fd, iov, iovcnt);
427
428 size = libc_readv (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700429 }
430
Dave Wallace048b1d62018-01-03 22:24:41 -0500431 if (VCOM_DEBUG > 2)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700432 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500433 if (size < 0)
434 {
435 int errno_val = errno;
436 perror (func_str);
437 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
438 "rv %d, errno = %d", getpid (), fd, fd,
439 func_str, size, errno_val);
440 errno = errno_val;
441 }
442 else
443 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
444 getpid (), fd, fd, size, size);
445 }
446 return size;
447}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700448
Dave Wallace048b1d62018-01-03 22:24:41 -0500449ssize_t
450write (int fd, const void *buf, size_t nbytes)
451{
452 const char *func_str;
453 ssize_t size = 0;
454 u32 sid = vcom_sid_from_fd (fd);
455
456 if ((errno = -vcom_init ()))
457 return -1;
458
459 if (sid != INVALID_SESSION_ID)
460 {
461 func_str = "vppcom_session_write";
462
463 if (VCOM_DEBUG > 2)
464 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
465 "sid %u (0x%x), buf %p, nbytes %u", getpid (),
466 fd, fd, func_str, sid, sid, buf, nbytes);
467
468 size = vppcom_session_write (sid, (void *) buf, nbytes);
469 if (size < 0)
470 {
471 errno = -size;
472 size = -1;
473 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700474 }
475 else
476 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500477 func_str = "libc_write";
478
479 if (VCOM_DEBUG > 2)
480 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
481 "buf %p, nbytes %u", getpid (),
482 fd, fd, func_str, buf, nbytes);
483
484 size = libc_write (fd, buf, nbytes);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700485 }
486
Dave Wallace048b1d62018-01-03 22:24:41 -0500487 if (VCOM_DEBUG > 2)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700488 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500489 if (size < 0)
490 {
491 int errno_val = errno;
492 perror (func_str);
493 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
494 "rv %d, errno = %d", getpid (), fd, fd,
495 func_str, size, errno_val);
496 errno = errno_val;
497 }
498 else
499 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
500 getpid (), fd, fd, size, size);
501 }
502 return size;
503}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700504
Dave Wallace048b1d62018-01-03 22:24:41 -0500505ssize_t
506writev (int fd, const struct iovec * iov, int iovcnt)
507{
508 const char *func_str;
509 ssize_t size = 0, total = 0;
510 u32 sid = vcom_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -0500511 int i, rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500512
513 /*
514 * Use [f]printf() instead of clib_warning() to prevent recursion SIGSEGV.
515 */
516
517 if ((errno = -vcom_init ()))
518 return -1;
519
520 if (sid != INVALID_SESSION_ID)
521 {
522 func_str = "vppcom_session_write";
523 do
524 {
525 for (i = 0; i < iovcnt; ++i)
526 {
527 if (VCOM_DEBUG > 4)
528 printf ("%s:%d: LDP<%d>: fd %d (0x%x): calling %s() [%d]: "
529 "sid %u (0x%x), buf %p, nbytes %ld, total %ld",
530 __func__, __LINE__, getpid (), fd, fd, func_str,
531 i, sid, sid, iov[i].iov_base, iov[i].iov_len, total);
532
533 rv = vppcom_session_write (sid, iov[i].iov_base,
534 iov[i].iov_len);
535 if (rv < 0)
536 break;
537 else
538 {
539 total += rv;
540 if (rv < iov[i].iov_len)
541 {
542 if (VCOM_DEBUG > 4)
543 printf ("%s:%d: LDP<%d>: fd %d (0x%x): "
544 "rv (%d) < iov[%d].iov_len (%ld)",
545 __func__, __LINE__, getpid (), fd, fd,
546 rv, i, iov[i].iov_len);
547 break;
548 }
549 }
550 }
551 }
552 while ((rv >= 0) && (total == 0));
553
554 if (rv < 0)
555 {
556 errno = -rv;
557 size = -1;
558 }
559 else
560 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700561 }
562 else
563 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500564 func_str = "libc_writev";
565
566 if (VCOM_DEBUG > 4)
567 printf ("%s:%d: LDP<%d>: fd %d (0x%x): calling %s(): "
568 "iov %p, iovcnt %d\n", __func__, __LINE__, getpid (),
569 fd, fd, func_str, iov, iovcnt);
570
571 size = libc_writev (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700572 }
573
Dave Wallace048b1d62018-01-03 22:24:41 -0500574 if (VCOM_DEBUG > 4)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700575 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500576 if (size < 0)
577 {
578 int errno_val = errno;
579 perror (func_str);
580 fprintf (stderr,
581 "%s:%d: LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
582 "rv %ld, errno = %d\n", __func__, __LINE__, getpid (), fd,
583 fd, func_str, size, errno_val);
584 errno = errno_val;
585 }
586 else
587 printf ("%s:%d: LDP<%d>: fd %d (0x%x): returning %ld\n",
588 __func__, __LINE__, getpid (), fd, fd, size);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700589 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500590 return size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700591}
592
593int
Dave Wallace048b1d62018-01-03 22:24:41 -0500594fcntl (int fd, int cmd, ...)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700595{
Dave Wallace048b1d62018-01-03 22:24:41 -0500596 const char *func_str = __func__;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700597 int rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500598 va_list ap;
599 u32 sid = vcom_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700600
Dave Wallace048b1d62018-01-03 22:24:41 -0500601 if ((errno = -vcom_init ()))
602 return -1;
603
604 va_start (ap, cmd);
605 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700606 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500607 int flags = va_arg (ap, int);
608 u32 size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700609
Dave Wallace048b1d62018-01-03 22:24:41 -0500610 size = sizeof (flags);
611 rv = -EOPNOTSUPP;
612 switch (cmd)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700613 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500614 case F_SETFL:
615 func_str = "vppcom_session_attr[SET_FLAGS]";
616 if (VCOM_DEBUG > 2)
617 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
618 "sid %u (0x%x) flags %d (0x%x), size %d",
619 getpid (), fd, fd, func_str, sid, sid,
620 flags, flags, size);
621
622 rv =
623 vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
624 break;
625
626 case F_GETFL:
627 func_str = "vppcom_session_attr[GET_FLAGS]";
628 if (VCOM_DEBUG > 2)
629 clib_warning
630 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
631 "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid,
632 sid, flags, flags, size);
633
634 rv =
635 vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags, &size);
636 if (rv == VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700637 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500638 if (VCOM_DEBUG > 2)
639 clib_warning ("LDP<%d>: fd %d (0x%x), cmd %d (F_GETFL): "
640 "%s() returned flags %d (0x%x)",
641 getpid (), fd, fd, cmd, func_str, flags, flags);
642 rv = flags;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700643 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700644 break;
645
646 default:
Dave Wallace048b1d62018-01-03 22:24:41 -0500647 rv = -EOPNOTSUPP;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700648 break;
649 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500650 if (rv < 0)
651 {
652 errno = -rv;
653 rv = -1;
654 }
655 }
656 else
657 {
658 func_str = "libc_vfcntl";
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700659
Dave Wallace048b1d62018-01-03 22:24:41 -0500660 if (VCOM_DEBUG > 2)
661 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
662 getpid (), fd, fd, func_str, cmd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700663
Dave Wallace048b1d62018-01-03 22:24:41 -0500664 rv = libc_vfcntl (fd, cmd, ap);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700665 }
666
Dave Wallace048b1d62018-01-03 22:24:41 -0500667 va_end (ap);
668
669 if (VCOM_DEBUG > 2)
670 {
671 if (rv < 0)
672 {
673 int errno_val = errno;
674 perror (func_str);
675 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
676 "rv %d, errno = %d", getpid (), fd, fd,
677 func_str, rv, errno_val);
678 errno = errno_val;
679 }
680 else
681 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
682 getpid (), fd, fd, rv, rv);
683 }
684 return rv;
685}
686
687int
688ioctl (int fd, unsigned long int cmd, ...)
689{
690 const char *func_str;
691 int rv;
692 va_list ap;
693 u32 sid = vcom_sid_from_fd (fd);
694
695 if ((errno = -vcom_init ()))
696 return -1;
697
698 va_start (ap, cmd);
699 if (sid != INVALID_SESSION_ID)
700 {
701 func_str = "vppcom_session_attr[GET_NREAD]";
702
703 switch (cmd)
704 {
705 case FIONREAD:
706 if (VCOM_DEBUG > 2)
707 clib_warning
708 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
709 getpid (), fd, fd, func_str, sid, sid);
710
711 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NREAD, 0, 0);
712 break;
713
714 case FIONBIO:
715 {
716 u32 flags = va_arg (ap, int) ? O_NONBLOCK : 0;
717 u32 size = sizeof (flags);
718
719 /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than
720 * non-blocking, the flags should be read here and merged
721 * with O_NONBLOCK.
722 */
723 if (VCOM_DEBUG > 2)
724 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
725 "sid %u (0x%x), flags %d (0x%x), size %d",
726 getpid (), fd, fd, func_str, sid, sid,
727 flags, flags, size);
728
729 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
730 &size);
731 }
732 break;
733
734 default:
735 rv = -EOPNOTSUPP;
736 break;
737 }
738 if (rv < 0)
739 {
740 errno = -rv;
741 rv = -1;
742 }
743 }
744 else
745 {
746 func_str = "libc_vioctl";
747
748 if (VCOM_DEBUG > 2)
749 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
750 getpid (), fd, fd, func_str, cmd);
751
752 rv = libc_vioctl (fd, cmd, ap);
753 }
754
755 if (VCOM_DEBUG > 2)
756 {
757 if (rv < 0)
758 {
759 int errno_val = errno;
760 perror (func_str);
761 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
762 "rv %d, errno = %d", getpid (), fd, fd,
763 func_str, rv, errno_val);
764 errno = errno_val;
765 }
766 else
767 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
768 getpid (), fd, fd, rv, rv);
769 }
770 va_end (ap);
771 return rv;
772}
773
774int
775vcom_pselect (int nfds, fd_set * __restrict readfds,
776 fd_set * __restrict writefds,
777 fd_set * __restrict exceptfds,
778 const struct timespec *__restrict timeout,
779 const __sigset_t * __restrict sigmask)
780{
781 int rv;
782 char *func_str = "##";
783 f64 time_out;
784 int fd;
785 uword sid_bits, sid_bits_set, libc_bits, libc_bits_set;
786 u32 minbits = clib_max (nfds, BITS (uword));
787 u32 sid;
788
789 if (nfds < 0)
790 {
791 errno = EINVAL;
792 return -1;
793 }
794
795 if (nfds <= vcom->sid_bit_val)
796 {
797 func_str = "libc_pselect";
798
799 if (VCOM_DEBUG > 3)
800 clib_warning
801 ("LDP<%d>: calling %s(): nfds %d, readfds %p, writefds %p, "
802 "exceptfds %p, timeout %p, sigmask %p", getpid (), func_str, nfds,
803 readfds, writefds, exceptfds, timeout, sigmask);
804
805 rv = libc_pselect (nfds, readfds, writefds, exceptfds,
806 timeout, sigmask);
807 goto done;
808 }
809
810 if (PREDICT_FALSE (vcom->sid_bit_val > FD_SETSIZE / 2))
811 {
812 clib_warning ("LDP<%d>: ERROR: VCOM sid bit value %d (0x%x) > "
813 "FD_SETSIZE/2 %d (0x%x)!", getpid (),
814 vcom->sid_bit_val, vcom->sid_bit_val,
815 FD_SETSIZE / 2, FD_SETSIZE / 2);
816 errno = EOVERFLOW;
817 return -1;
818 }
819
820 if (timeout)
821 {
822 time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
823 (f64) 0 : (f64) timeout->tv_sec +
824 (f64) timeout->tv_nsec / (f64) 1000000000 +
825 (f64) (timeout->tv_nsec % 1000000000) / (f64) 1000000000;
826
827 /* select as fine grained sleep */
828 if (!nfds)
829 {
830 if (VCOM_DEBUG > 3)
831 clib_warning ("LDP<%d>: sleeping for %f seconds",
832 getpid (), time_out);
833
834 time_out += clib_time_now (&vcom->clib_time);
835 while (clib_time_now (&vcom->clib_time) < time_out)
836 ;
837 return 0;
838 }
839 }
840 else if (!nfds)
841 {
842 errno = EINVAL;
843 return -1;
844 }
845 else
846 time_out = -1;
847
848 sid_bits = libc_bits = 0;
849 if (readfds)
850 {
851 clib_bitmap_validate (vcom->sid_rd_bitmap, minbits);
852 clib_bitmap_validate (vcom->libc_rd_bitmap, minbits);
853 clib_bitmap_validate (vcom->rd_bitmap, minbits);
854 clib_memcpy (vcom->rd_bitmap, readfds,
855 vec_len (vcom->rd_bitmap) * sizeof (clib_bitmap_t));
856 FD_ZERO (readfds);
857
858 /* *INDENT-OFF* */
859 clib_bitmap_foreach (fd, vcom->rd_bitmap,
860 ({
861 sid = vcom_sid_from_fd (fd);
862 if (VCOM_DEBUG > 3)
863 clib_warning ("LDP<%d>: readfds: fd %d (0x%x), sid %u (0x%x)",
864 getpid (), fd, fd, sid, sid);
865 if (sid == INVALID_SESSION_ID)
866 clib_bitmap_set_no_check (vcom->libc_rd_bitmap, fd, 1);
867 else
868 clib_bitmap_set_no_check (vcom->sid_rd_bitmap, sid, 1);
869 }));
870 /* *INDENT-ON* */
871
872 sid_bits_set = clib_bitmap_last_set (vcom->sid_rd_bitmap) + 1;
873 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
874
875 libc_bits_set = clib_bitmap_last_set (vcom->libc_rd_bitmap) + 1;
876 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
877
878 if (VCOM_DEBUG > 3)
879 clib_warning ("LDP<%d>: readfds: sid_bits_set %d, sid_bits %d, "
880 "libc_bits_set %d, libc_bits %d", getpid (),
881 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
882 }
883 if (writefds)
884 {
885 clib_bitmap_validate (vcom->sid_wr_bitmap, minbits);
886 clib_bitmap_validate (vcom->libc_wr_bitmap, minbits);
887 clib_bitmap_validate (vcom->wr_bitmap, minbits);
888 clib_memcpy (vcom->wr_bitmap, writefds,
889 vec_len (vcom->wr_bitmap) * sizeof (clib_bitmap_t));
890 FD_ZERO (writefds);
891
892 /* *INDENT-OFF* */
893 clib_bitmap_foreach (fd, vcom->wr_bitmap,
894 ({
895 sid = vcom_sid_from_fd (fd);
896 if (VCOM_DEBUG > 3)
897 clib_warning ("LDP<%d>: writefds: fd %d (0x%x), sid %u (0x%x)",
898 getpid (), fd, fd, sid, sid);
899 if (sid == INVALID_SESSION_ID)
900 clib_bitmap_set_no_check (vcom->libc_wr_bitmap, fd, 1);
901 else
902 clib_bitmap_set_no_check (vcom->sid_wr_bitmap, sid, 1);
903 }));
904 /* *INDENT-ON* */
905
906 sid_bits_set = clib_bitmap_last_set (vcom->sid_wr_bitmap) + 1;
907 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
908
909 libc_bits_set = clib_bitmap_last_set (vcom->libc_wr_bitmap) + 1;
910 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
911
912 if (VCOM_DEBUG > 3)
913 clib_warning ("LDP<%d>: writefds: sid_bits_set %d, sid_bits %d, "
914 "libc_bits_set %d, libc_bits %d", getpid (),
915 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
916 }
917 if (exceptfds)
918 {
919 clib_bitmap_validate (vcom->sid_ex_bitmap, minbits);
920 clib_bitmap_validate (vcom->libc_ex_bitmap, minbits);
921 clib_bitmap_validate (vcom->ex_bitmap, minbits);
922 clib_memcpy (vcom->ex_bitmap, exceptfds,
923 vec_len (vcom->ex_bitmap) * sizeof (clib_bitmap_t));
924 FD_ZERO (exceptfds);
925
926 /* *INDENT-OFF* */
927 clib_bitmap_foreach (fd, vcom->ex_bitmap,
928 ({
929 sid = vcom_sid_from_fd (fd);
930 if (VCOM_DEBUG > 3)
931 clib_warning ("LDP<%d>: exceptfds: fd %d (0x%x), sid %u (0x%x)",
932 getpid (), fd, fd, sid, sid);
933 if (sid == INVALID_SESSION_ID)
934 clib_bitmap_set_no_check (vcom->libc_ex_bitmap, fd, 1);
935 else
936 clib_bitmap_set_no_check (vcom->sid_ex_bitmap, sid, 1);
937 }));
938 /* *INDENT-ON* */
939
940 sid_bits_set = clib_bitmap_last_set (vcom->sid_ex_bitmap) + 1;
941 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
942
943 libc_bits_set = clib_bitmap_last_set (vcom->libc_ex_bitmap) + 1;
944 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
945
946 if (VCOM_DEBUG > 3)
947 clib_warning ("LDP<%d>: exceptfds: sid_bits_set %d, sid_bits %d, "
948 "libc_bits_set %d, libc_bits %d", getpid (),
949 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
950 }
951
952 if (PREDICT_FALSE (!sid_bits && !libc_bits))
953 {
954 errno = EINVAL;
955 rv = -1;
956 goto done;
957 }
958
959 do
960 {
961 if (sid_bits)
962 {
963 if (!vcom->select_vcl)
964 {
965 func_str = "vppcom_select";
966
967 if (readfds)
968 clib_memcpy (vcom->rd_bitmap, vcom->sid_rd_bitmap,
969 vec_len (vcom->rd_bitmap) *
970 sizeof (clib_bitmap_t));
971 if (writefds)
972 clib_memcpy (vcom->wr_bitmap, vcom->sid_wr_bitmap,
973 vec_len (vcom->wr_bitmap) *
974 sizeof (clib_bitmap_t));
975 if (exceptfds)
976 clib_memcpy (vcom->ex_bitmap, vcom->sid_ex_bitmap,
977 vec_len (vcom->ex_bitmap) *
978 sizeof (clib_bitmap_t));
979
980 rv = vppcom_select (sid_bits,
981 readfds ? vcom->rd_bitmap : NULL,
982 writefds ? vcom->wr_bitmap : NULL,
983 exceptfds ? vcom->ex_bitmap : NULL, 0);
984 if (rv < 0)
985 {
986 errno = -rv;
987 rv = -1;
988 }
989 else if (rv > 0)
990 {
991 if (readfds)
992 {
993 /* *INDENT-OFF* */
994 clib_bitmap_foreach (sid, vcom->rd_bitmap,
995 ({
996 fd = vcom_fd_from_sid (sid);
997 if (PREDICT_FALSE (fd < 0))
998 {
999 errno = EBADFD;
1000 rv = -1;
1001 goto done;
1002 }
1003 FD_SET (fd, readfds);
1004 }));
1005 /* *INDENT-ON* */
1006 }
1007 if (writefds)
1008 {
1009 /* *INDENT-OFF* */
1010 clib_bitmap_foreach (sid, vcom->wr_bitmap,
1011 ({
1012 fd = vcom_fd_from_sid (sid);
1013 if (PREDICT_FALSE (fd < 0))
1014 {
1015 errno = EBADFD;
1016 rv = -1;
1017 goto done;
1018 }
1019 FD_SET (fd, writefds);
1020 }));
1021 /* *INDENT-ON* */
1022 }
1023 if (exceptfds)
1024 {
1025 /* *INDENT-OFF* */
1026 clib_bitmap_foreach (sid, vcom->ex_bitmap,
1027 ({
1028 fd = vcom_fd_from_sid (sid);
1029 if (PREDICT_FALSE (fd < 0))
1030 {
1031 errno = EBADFD;
1032 rv = -1;
1033 goto done;
1034 }
1035 FD_SET (fd, exceptfds);
1036 }));
1037 /* *INDENT-ON* */
1038 }
1039 vcom->select_vcl = 1;
1040 goto done;
1041 }
1042 }
1043 else
1044 vcom->select_vcl = 0;
1045 }
1046 if (libc_bits)
1047 {
1048 struct timespec tspec;
1049
1050 func_str = "libc_pselect";
1051
1052 if (readfds)
1053 clib_memcpy (readfds, vcom->libc_rd_bitmap,
1054 vec_len (vcom->rd_bitmap) * sizeof (clib_bitmap_t));
1055 if (writefds)
1056 clib_memcpy (writefds, vcom->libc_wr_bitmap,
1057 vec_len (vcom->wr_bitmap) * sizeof (clib_bitmap_t));
1058 if (exceptfds)
1059 clib_memcpy (exceptfds, vcom->libc_ex_bitmap,
1060 vec_len (vcom->ex_bitmap) * sizeof (clib_bitmap_t));
1061 tspec.tv_sec = tspec.tv_nsec = 0;
1062 rv = libc_pselect (libc_bits,
1063 readfds ? readfds : NULL,
1064 writefds ? writefds : NULL,
1065 exceptfds ? exceptfds : NULL, &tspec, sigmask);
1066 if (rv != 0)
1067 goto done;
1068 }
1069 }
1070 while ((time_out == -1) || (clib_time_now (&vcom->clib_time) < time_out));
1071 rv = 0;
1072
1073done:
1074 /* TBD: set timeout to amount of time left */
1075 vec_reset_length (vcom->rd_bitmap);
1076 vec_reset_length (vcom->sid_rd_bitmap);
1077 vec_reset_length (vcom->libc_rd_bitmap);
1078 vec_reset_length (vcom->wr_bitmap);
1079 vec_reset_length (vcom->sid_wr_bitmap);
1080 vec_reset_length (vcom->libc_wr_bitmap);
1081 vec_reset_length (vcom->ex_bitmap);
1082 vec_reset_length (vcom->sid_ex_bitmap);
1083 vec_reset_length (vcom->libc_ex_bitmap);
1084
1085 if (VCOM_DEBUG > 3)
1086 {
1087 if (rv < 0)
1088 {
1089 int errno_val = errno;
1090 perror (func_str);
1091 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1092 "rv %d, errno = %d", getpid (),
1093 func_str, rv, errno_val);
1094 errno = errno_val;
1095 }
1096 else
1097 clib_warning ("LDP<%d>: returning %d (0x%x)", getpid (), rv, rv);
1098 }
1099 return rv;
1100}
1101
1102int
1103select (int nfds, fd_set * __restrict readfds,
1104 fd_set * __restrict writefds,
1105 fd_set * __restrict exceptfds, struct timeval *__restrict timeout)
1106{
1107 struct timespec tspec;
1108
1109 if (timeout)
1110 {
1111 tspec.tv_sec = timeout->tv_sec;
1112 tspec.tv_nsec = timeout->tv_usec * 1000;
1113 }
1114 return vcom_pselect (nfds, readfds, writefds, exceptfds,
1115 timeout ? &tspec : NULL, NULL);
1116}
1117
1118#ifdef __USE_XOPEN2K
1119int
1120pselect (int nfds, fd_set * __restrict readfds,
1121 fd_set * __restrict writefds,
1122 fd_set * __restrict exceptfds,
1123 const struct timespec *__restrict timeout,
1124 const __sigset_t * __restrict sigmask)
1125{
1126 return vcom_pselect (nfds, readfds, writefds, exceptfds, timeout, 0);
1127}
1128#endif
1129
1130int
1131socket (int domain, int type, int protocol)
1132{
1133 const char *func_str;
1134 int rv;
1135 u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
1136 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1137
1138 if ((errno = -vcom_init ()))
1139 return -1;
1140
1141 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1142 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
1143 {
1144 int sid;
1145 u32 vrf = VPPCOM_VRF_DEFAULT;
1146 u8 proto = ((sock_type == SOCK_DGRAM) ?
1147 VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
1148
1149 func_str = "vppcom_session_create";
1150
1151 if (VCOM_DEBUG > 0)
1152 clib_warning ("LDP<%d>: : calling %s(): vrf %u, "
1153 "proto %u (%s), is_nonblocking %u",
1154 getpid (), func_str, vrf, proto,
1155 vppcom_proto_str (proto), is_nonblocking);
1156
1157 sid = vppcom_session_create (vrf, proto, is_nonblocking);
1158 if (sid < 0)
1159 {
1160 errno = -sid;
1161 rv = -1;
1162 }
1163 else
1164 {
1165 func_str = "vcom_fd_from_sid";
1166 rv = vcom_fd_from_sid (sid);
1167 if (rv < 0)
1168 {
1169 (void) vppcom_session_close (sid);
1170 errno = -rv;
1171 rv = -1;
1172 }
1173 }
1174 }
1175 else
1176 {
1177 func_str = "libc_socket";
1178
1179 if (VCOM_DEBUG > 0)
1180 clib_warning ("LDP<%d>: : calling %s()", getpid (), func_str);
1181
1182 rv = libc_socket (domain, type, protocol);
1183 }
1184
1185 if (VCOM_DEBUG > 0)
1186 {
1187 if (rv < 0)
1188 {
1189 int errno_val = errno;
1190 perror (func_str);
1191 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1192 "rv %d, errno = %d",
1193 getpid (), func_str, rv, errno_val);
1194 errno = errno_val;
1195 }
1196 else
1197 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1198 }
1199 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001200}
1201
1202/*
1203 * Create two new sockets, of type TYPE in domain DOMAIN and using
1204 * protocol PROTOCOL, which are connected to each other, and put file
1205 * descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
1206 * one will be chosen automatically.
1207 * Returns 0 on success, -1 for errors.
1208 * */
1209int
Dave Wallace048b1d62018-01-03 22:24:41 -05001210socketpair (int domain, int type, int protocol, int fds[2])
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001211{
Dave Wallace048b1d62018-01-03 22:24:41 -05001212 const char *func_str;
1213 int rv;
1214 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1215
1216 if ((errno = -vcom_init ()))
1217 return -1;
1218
1219 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1220 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001221 {
Dave Wallace8aaba562018-01-18 17:21:19 -05001222 func_str = __func__;
1223
Dave Wallace048b1d62018-01-03 22:24:41 -05001224 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1225 errno = ENOSYS;
1226 rv = -1;
1227 }
1228 else
1229 {
1230 func_str = "libc_socket";
1231
1232 if (VCOM_DEBUG > 1)
1233 clib_warning ("LDP<%d>: : calling %s()", getpid (), func_str);
1234
1235 rv = libc_socket (domain, type, protocol);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001236 }
1237
Dave Wallace048b1d62018-01-03 22:24:41 -05001238 if (VCOM_DEBUG > 1)
1239 {
1240 if (rv < 0)
1241 {
1242 int errno_val = errno;
1243 perror (func_str);
1244 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1245 "rv %d, errno = %d",
1246 getpid (), func_str, rv, errno_val);
1247 errno = errno_val;
1248 }
1249 else
1250 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1251 }
1252 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001253}
1254
1255int
Dave Wallace048b1d62018-01-03 22:24:41 -05001256bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001257{
1258 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001259 const char *func_str;
1260 u32 sid = vcom_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001261
Dave Wallace048b1d62018-01-03 22:24:41 -05001262 if ((errno = -vcom_init ()))
1263 return -1;
1264
1265 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001266 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001267 vppcom_endpt_t ep;
1268
1269 func_str = "vppcom_session_bind";
1270
1271 ep.vrf = VPPCOM_VRF_DEFAULT;
1272 switch (addr->sa_family)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001273 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001274 case AF_INET:
1275 if (len != sizeof (struct sockaddr_in))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001276 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001277 clib_warning
1278 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1279 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1280 errno = EINVAL;
1281 rv = -1;
1282 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001283 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001284 ep.is_ip4 = VPPCOM_IS_IP4;
1285 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1286 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1287 break;
1288
1289 case AF_INET6:
1290 if (len != sizeof (struct sockaddr_in6))
1291 {
1292 clib_warning
1293 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1294 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1295 errno = EINVAL;
1296 rv = -1;
1297 goto done;
1298 }
1299 ep.is_ip4 = VPPCOM_IS_IP6;
1300 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1301 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001302 break;
1303
1304 default:
Dave Wallace048b1d62018-01-03 22:24:41 -05001305 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): "
1306 "Unsupported address family %u!",
1307 getpid (), fd, fd, sid, sid, addr->sa_family);
1308 errno = EAFNOSUPPORT;
1309 rv = -1;
1310 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001311 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001312 if (VCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001313 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1314 "addr %p, len %u",
1315 getpid (), fd, fd, func_str, sid, sid, addr, len);
1316
1317 rv = vppcom_session_bind (sid, &ep);
1318 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001319 {
1320 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001321 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001322 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001323 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001324 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001325 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001326 func_str = "libc_bind";
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001327
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001328 if (VCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001329 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1330 "addr %p, len %u",
1331 getpid (), fd, fd, func_str, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001332
Dave Wallace048b1d62018-01-03 22:24:41 -05001333 rv = libc_bind (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001334 }
1335
Dave Wallace048b1d62018-01-03 22:24:41 -05001336done:
1337 if (VCOM_DEBUG > 0)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001338 {
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001339 if (rv < 0)
1340 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001341 int errno_val = errno;
1342 perror (func_str);
1343 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1344 "rv %d, errno = %d", getpid (), fd, fd,
1345 func_str, rv, errno_val);
1346 errno = errno_val;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001347 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001348 else
1349 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1350 getpid (), fd, fd, rv, rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001351 }
1352 return rv;
1353}
1354
1355static inline int
Dave Wallace048b1d62018-01-03 22:24:41 -05001356vcom_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
1357 vppcom_endpt_t * ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001358{
Dave Wallace048b1d62018-01-03 22:24:41 -05001359 int rv = 0;
1360 int sa_len, copy_len;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001361
Dave Wallace048b1d62018-01-03 22:24:41 -05001362 if ((errno = -vcom_init ()))
1363 return -1;
1364
1365 if (addr && len && ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001366 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001367 addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6;
1368 switch (addr->sa_family)
1369 {
1370 case AF_INET:
1371 ((struct sockaddr_in *) addr)->sin_port = ep->port;
1372 if (*len > sizeof (struct sockaddr_in))
1373 *len = sizeof (struct sockaddr_in);
1374 sa_len = sizeof (struct sockaddr_in) - sizeof (struct in_addr);
1375 copy_len = *len - sa_len;
1376 if (copy_len > 0)
1377 memcpy (&((struct sockaddr_in *) addr)->sin_addr, ep->ip,
1378 copy_len);
1379 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001380
Dave Wallace048b1d62018-01-03 22:24:41 -05001381 case AF_INET6:
1382 ((struct sockaddr_in6 *) addr)->sin6_port = ep->port;
1383 if (*len > sizeof (struct sockaddr_in6))
1384 *len = sizeof (struct sockaddr_in6);
1385 sa_len = sizeof (struct sockaddr_in6) - sizeof (struct in6_addr);
1386 copy_len = *len - sa_len;
1387 if (copy_len > 0)
1388 memcpy (((struct sockaddr_in6 *) addr)->sin6_addr.
1389 __in6_u.__u6_addr8, ep->ip, copy_len);
1390 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001391
Dave Wallace048b1d62018-01-03 22:24:41 -05001392 default:
1393 /* Not possible */
1394 rv = -EAFNOSUPPORT;
1395 break;
1396 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001397 }
Dave Wallacee695cb42017-11-02 22:04:42 -04001398 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001399}
1400
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001401int
Dave Wallace048b1d62018-01-03 22:24:41 -05001402getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001403{
1404 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001405 const char *func_str;
1406 u32 sid = vcom_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001407
Dave Wallace048b1d62018-01-03 22:24:41 -05001408 if ((errno = -vcom_init ()))
1409 return -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001410
Dave Wallace048b1d62018-01-03 22:24:41 -05001411 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001412 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001413 vppcom_endpt_t ep;
1414 u8 addr_buf[sizeof (struct in6_addr)];
1415 u32 size = sizeof (ep);
1416
1417 ep.ip = addr_buf;
1418 func_str = "vppcom_session_attr[GET_LCL_ADDR]";
1419
1420 if (VCOM_DEBUG > 2)
1421 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1422 "addr %p, len %u",
1423 getpid (), fd, fd, func_str, sid, sid, addr, len);
1424
1425 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
1426 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001427 {
1428 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001429 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001430 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001431 else
1432 {
1433 rv = vcom_copy_ep_to_sockaddr (addr, len, &ep);
1434 if (rv != VPPCOM_OK)
1435 {
1436 errno = -rv;
1437 rv = -1;
1438 }
1439 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001440 }
1441 else
1442 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001443 func_str = "libc_getsockname";
1444
1445 if (VCOM_DEBUG > 2)
1446 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1447 "addr %p, len %u",
1448 getpid (), fd, fd, func_str, addr, len);
1449
1450 rv = libc_getsockname (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001451 }
1452
Dave Wallace048b1d62018-01-03 22:24:41 -05001453 if (VCOM_DEBUG > 2)
1454 {
1455 if (rv < 0)
1456 {
1457 int errno_val = errno;
1458 perror (func_str);
1459 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1460 "rv %d, errno = %d", getpid (), fd, fd,
1461 func_str, rv, errno_val);
1462 errno = errno_val;
1463 }
1464 else
1465 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1466 getpid (), fd, fd, rv, rv);
1467 }
1468 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001469}
1470
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001471int
Dave Wallace048b1d62018-01-03 22:24:41 -05001472connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001473{
Dave Wallace048b1d62018-01-03 22:24:41 -05001474 int rv;
1475 const char *func_str = __func__;
1476 u32 sid = vcom_sid_from_fd (fd);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001477
Dave Wallace048b1d62018-01-03 22:24:41 -05001478 if ((errno = -vcom_init ()))
1479 return -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001480
Dave Wallace048b1d62018-01-03 22:24:41 -05001481 if (!addr)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001482 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001483 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): NULL addr, len %u",
1484 getpid (), fd, fd, len);
1485 errno = EINVAL;
1486 rv = -1;
1487 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001488 }
1489
Dave Wallace048b1d62018-01-03 22:24:41 -05001490 if (sid != INVALID_SESSION_ID)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001491 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001492 vppcom_endpt_t ep;
1493
1494 func_str = "vppcom_session_connect";
1495
1496 ep.vrf = VPPCOM_VRF_DEFAULT;
1497 switch (addr->sa_family)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001498 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001499 case AF_INET:
1500 if (len != sizeof (struct sockaddr_in))
1501 {
1502 clib_warning
1503 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1504 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1505 errno = EINVAL;
1506 rv = -1;
1507 goto done;
1508 }
1509 ep.is_ip4 = VPPCOM_IS_IP4;
1510 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1511 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1512 break;
1513
1514 case AF_INET6:
1515 if (len != sizeof (struct sockaddr_in6))
1516 {
1517 clib_warning
1518 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1519 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1520 errno = EINVAL;
1521 rv = -1;
1522 goto done;
1523 }
1524 ep.is_ip4 = VPPCOM_IS_IP6;
1525 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1526 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
1527 break;
1528
1529 default:
1530 clib_warning ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): "
1531 "Unsupported address family %u!",
1532 getpid (), fd, fd, sid, sid, addr->sa_family);
1533 errno = EAFNOSUPPORT;
1534 rv = -1;
1535 goto done;
1536 }
1537 if (VCOM_DEBUG > 0)
1538 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x) "
1539 "addr %p len %u",
1540 getpid (), fd, fd, func_str, sid, sid, addr, len);
1541
1542 rv = vppcom_session_connect (sid, &ep);
1543 if (rv != VPPCOM_OK)
1544 {
1545 errno = -rv;
1546 rv = -1;
1547 }
1548 }
1549 else
1550 {
1551 func_str = "libc_connect";
1552
1553 if (VCOM_DEBUG > 0)
1554 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1555 "addr %p, len %u",
1556 getpid (), fd, fd, func_str, addr, len);
1557
1558 rv = libc_connect (fd, addr, len);
1559 }
1560
1561done:
1562 if (VCOM_DEBUG > 0)
1563 {
1564 if (rv < 0)
1565 {
1566 int errno_val = errno;
1567 perror (func_str);
1568 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1569 "rv %d, errno = %d", getpid (), fd, fd,
1570 func_str, rv, errno_val);
1571 errno = errno_val;
1572 }
1573 else
1574 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1575 getpid (), fd, fd, rv, rv);
1576 }
1577 return rv;
1578}
1579
1580int
1581getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
1582{
1583 int rv;
1584 const char *func_str;
1585 u32 sid = vcom_sid_from_fd (fd);
1586
1587 if ((errno = -vcom_init ()))
1588 return -1;
1589
Dave Wallace048b1d62018-01-03 22:24:41 -05001590 if (sid != INVALID_SESSION_ID)
1591 {
1592 vppcom_endpt_t ep;
1593 u8 addr_buf[sizeof (struct in6_addr)];
1594 u32 size = sizeof (ep);
1595
1596 ep.ip = addr_buf;
1597 func_str = "vppcom_session_attr[GET_PEER_ADDR]";
1598
1599 if (VCOM_DEBUG > 2)
1600 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1601 "addr %p, len %u",
1602 getpid (), fd, fd, func_str, sid, sid, addr, len);
1603
1604 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
1605 if (rv != VPPCOM_OK)
1606 {
1607 errno = -rv;
1608 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001609 }
1610 else
1611 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001612 rv = vcom_copy_ep_to_sockaddr (addr, len, &ep);
1613 if (rv != VPPCOM_OK)
1614 {
1615 errno = -rv;
1616 rv = -1;
1617 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001618 }
1619 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001620 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001621 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001622 func_str = "libc_getpeername";
1623
1624 if (VCOM_DEBUG > 2)
1625 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1626 "addr %p, len %u",
1627 getpid (), fd, fd, func_str, addr, len);
1628
1629 rv = libc_getpeername (fd, addr, len);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001630 }
1631
Dave Wallace048b1d62018-01-03 22:24:41 -05001632 if (VCOM_DEBUG > 2)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001633 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001634 if (rv < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001635 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001636 int errno_val = errno;
1637 perror (func_str);
1638 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1639 "rv %d, errno = %d", getpid (), fd, fd,
1640 func_str, rv, errno_val);
1641 errno = errno_val;
1642 }
1643 else
1644 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1645 getpid (), fd, fd, rv, rv);
1646 }
1647 return rv;
1648}
1649
1650ssize_t
1651send (int fd, const void *buf, size_t n, int flags)
1652{
1653 ssize_t size;
1654 const char *func_str;
1655 u32 sid = vcom_sid_from_fd (fd);
1656
1657 if ((errno = -vcom_init ()))
1658 return -1;
1659
1660 if (sid != INVALID_SESSION_ID)
1661 {
1662
1663 func_str = "vppcom_session_sendto";
1664
1665 if (VCOM_DEBUG > 2)
1666 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1667 "buf %p, n %u, flags 0x%x",
1668 getpid (), fd, fd, func_str, sid, sid, buf, n, flags);
1669
1670 size = vppcom_session_sendto (sid, (void *) buf, n, flags, NULL);
1671 if (size != VPPCOM_OK)
1672 {
1673 errno = -size;
1674 size = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001675 }
1676 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001677 else
1678 {
1679 func_str = "libc_send";
1680
1681 if (VCOM_DEBUG > 2)
1682 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1683 "buf %p, n %u, flags 0x%x",
1684 getpid (), fd, fd, func_str, buf, n, flags);
1685
1686 size = libc_send (fd, buf, n, flags);
1687 }
1688
1689 if (VCOM_DEBUG > 2)
1690 {
1691 if (size < 0)
1692 {
1693 int errno_val = errno;
1694 perror (func_str);
1695 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1696 "rv %d, errno = %d", getpid (), fd, fd,
1697 func_str, size, errno_val);
1698 errno = errno_val;
1699 }
1700 else
1701 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1702 getpid (), fd, fd, size, size);
1703 }
1704 return size;
1705}
1706
1707ssize_t
1708sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
1709{
1710 ssize_t size = 0;
1711 const char *func_str;
1712 u32 sid = vcom_sid_from_fd (out_fd);
1713
1714 if ((errno = -vcom_init ()))
1715 return -1;
1716
1717 if (sid != INVALID_SESSION_ID)
1718 {
1719 int rv;
1720 ssize_t results = 0;
1721 size_t n_bytes_left = len;
1722 size_t bytes_to_read;
1723 int nbytes;
1724 int errno_val;
1725 u8 eagain = 0;
1726 u32 flags, flags_len = sizeof (flags);
1727
1728 func_str = "vppcom_session_attr[GET_FLAGS]";
1729 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
1730 &flags_len);
1731 if (PREDICT_FALSE (rv != VPPCOM_OK))
1732 {
1733 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1734 "sid %u (0x%x), returned %d (%s)!", getpid (),
1735 out_fd, out_fd, func_str, sid, sid, rv,
1736 vppcom_retval_str (rv));
1737
1738 vec_reset_length (vcom->io_buffer);
1739 errno = -rv;
1740 size = -1;
1741 goto done;
1742 }
1743
1744 if (offset)
1745 {
1746 off_t off = lseek (in_fd, *offset, SEEK_SET);
1747 if (PREDICT_FALSE (off == -1))
1748 {
1749 func_str = "lseek";
1750 errno_val = errno;
1751 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1752 "SEEK_SET failed: in_fd %d, offset %p, "
1753 "*offset %ld, rv %ld, errno %d", getpid (),
1754 out_fd, out_fd, in_fd, offset, *offset, off,
1755 errno_val);
1756 errno = errno_val;
1757 size = -1;
1758 goto done;
1759 }
1760
1761 ASSERT (off == *offset);
1762 }
1763
1764 do
1765 {
1766 func_str = "vppcom_session_attr[GET_NWRITE]";
1767 size = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NWRITE, 0, 0);
1768 if (size < 0)
1769 {
1770 clib_warning
1771 ("LDP<%d>: ERROR: fd %d (0x%x): %s(): sid %u (0x%x), "
1772 "returned %d (%s)!", getpid (), out_fd, out_fd, func_str,
1773 sid, sid, size, vppcom_retval_str (size));
1774 vec_reset_length (vcom->io_buffer);
1775 errno = -size;
1776 size = -1;
1777 goto done;
1778 }
1779
1780 bytes_to_read = size;
1781 if (VCOM_DEBUG > 2)
1782 clib_warning
1783 ("LDP<%d>: fd %d (0x%x): called %s(): sid %u (0x%x), "
1784 "results %ld, n_bytes_left %lu, bytes_to_read %lu", getpid (),
1785 out_fd, out_fd, func_str, sid, sid, results, n_bytes_left,
1786 bytes_to_read);
1787
1788 if (bytes_to_read == 0)
1789 {
1790 if (flags & O_NONBLOCK)
1791 {
1792 if (!results)
1793 {
1794 if (VCOM_DEBUG > 2)
1795 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1796 "EAGAIN",
1797 getpid (), out_fd, out_fd, sid, sid);
1798 eagain = 1;
1799 }
1800 goto update_offset;
1801 }
1802 else
1803 continue;
1804 }
1805 bytes_to_read = clib_min (n_bytes_left, bytes_to_read);
1806 vec_validate (vcom->io_buffer, bytes_to_read);
1807 nbytes = libc_read (in_fd, vcom->io_buffer, bytes_to_read);
1808 if (nbytes < 0)
1809 {
1810 func_str = "libc_read";
1811 errno_val = errno;
1812 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): in_fd (%d), "
1813 "io_buffer %p, bytes_to_read %lu, rv %d, "
1814 "errno %d", getpid (), out_fd, out_fd, func_str,
1815 in_fd, vcom->io_buffer, bytes_to_read, nbytes,
1816 errno_val);
1817 errno = errno_val;
1818
1819 if (results == 0)
1820 {
1821 vec_reset_length (vcom->io_buffer);
1822 size = -1;
1823 goto done;
1824 }
1825 goto update_offset;
1826 }
1827 func_str = "vppcom_session_write";
1828 if (VCOM_DEBUG > 2)
1829 clib_warning
1830 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1831 "buf %p, nbytes %u: results %d, n_bytes_left %d", getpid (),
1832 out_fd, out_fd, func_str, sid, sid, vcom->io_buffer, nbytes,
1833 results, n_bytes_left);
1834
1835 size = vppcom_session_write (sid, vcom->io_buffer, nbytes);
1836 if (size < 0)
1837 {
1838 if (size == VPPCOM_EAGAIN)
1839 {
1840 if (flags & O_NONBLOCK)
1841 {
1842 if (!results)
1843 {
1844 if (VCOM_DEBUG > 2)
1845 clib_warning
1846 ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1847 "EAGAIN", getpid (), out_fd, out_fd, sid, sid);
1848 eagain = 1;
1849 }
1850 goto update_offset;
1851 }
1852 else
1853 continue;
1854 }
1855 else
1856 {
1857 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s():"
1858 "sid %u, io_buffer %p, nbytes %u "
1859 "returned %d (%s)",
1860 getpid (), out_fd, out_fd, func_str,
1861 sid, vcom->io_buffer, nbytes,
1862 size, vppcom_retval_str (size));
1863 }
1864 if (results == 0)
1865 {
1866 vec_reset_length (vcom->io_buffer);
1867 errno = -size;
1868 size = -1;
1869 goto done;
1870 }
1871 goto update_offset;
1872 }
1873
1874 results += nbytes;
1875 ASSERT (n_bytes_left >= nbytes);
1876 n_bytes_left = n_bytes_left - nbytes;
1877 }
1878 while (n_bytes_left > 0);
1879
1880 update_offset:
1881 vec_reset_length (vcom->io_buffer);
1882 if (offset)
1883 {
1884 off_t off = lseek (in_fd, *offset, SEEK_SET);
1885 if (PREDICT_FALSE (off == -1))
1886 {
1887 func_str = "lseek";
1888 errno_val = errno;
1889 clib_warning ("LDP<%d>: ERROR: %s(): SEEK_SET failed: "
1890 "in_fd %d, offset %p, *offset %ld, "
1891 "rv %ld, errno %d", getpid (), in_fd,
1892 offset, *offset, off, errno_val);
1893 errno = errno_val;
1894 size = -1;
1895 goto done;
1896 }
1897
1898 ASSERT (off == *offset);
1899 *offset += results + 1;
1900 }
1901 if (eagain)
1902 {
1903 errno = EAGAIN;
1904 size = -1;
1905 }
1906 else
1907 size = results;
1908 }
1909 else
1910 {
1911 func_str = "libc_send";
1912
1913 if (VCOM_DEBUG > 2)
1914 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1915 "in_fd %d, offset %p, len %u",
1916 getpid (), out_fd, out_fd, func_str,
1917 in_fd, offset, len);
1918
1919 size = libc_sendfile (out_fd, in_fd, offset, len);
1920 }
1921
1922done:
1923 if (VCOM_DEBUG > 2)
1924 {
1925 if (size < 0)
1926 {
1927 int errno_val = errno;
1928 perror (func_str);
1929 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1930 "rv %d, errno = %d", getpid (), out_fd, out_fd,
1931 func_str, size, errno_val);
1932 errno = errno_val;
1933 }
1934 else
1935 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1936 getpid (), out_fd, out_fd, size, size);
1937 }
1938 return size;
1939}
1940
1941ssize_t
1942sendfile64 (int out_fd, int in_fd, off_t * offset, size_t len)
1943{
1944 return sendfile (out_fd, in_fd, offset, len);
1945}
1946
1947ssize_t
1948recv (int fd, void *buf, size_t n, int flags)
1949{
1950 ssize_t size;
1951 const char *func_str;
1952 u32 sid = vcom_sid_from_fd (fd);
1953
1954 if ((errno = -vcom_init ()))
1955 return -1;
1956
1957 if (sid != INVALID_SESSION_ID)
1958 {
1959 func_str = "vppcom_session_recvfrom";
1960
1961 if (VCOM_DEBUG > 2)
1962 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1963 "sid %u (0x%x), buf %p, n %u, flags 0x%x", getpid (),
1964 fd, fd, func_str, sid, sid, buf, n, flags);
1965
1966 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
1967 if (size < 0)
1968 {
1969 errno = -size;
1970 size = -1;
1971 }
1972 }
1973 else
1974 {
1975 func_str = "libc_recv";
1976
1977 if (VCOM_DEBUG > 2)
1978 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1979 "buf %p, n %u, flags 0x%x", getpid (),
1980 fd, fd, func_str, buf, n, flags);
1981
1982 size = libc_recv (fd, buf, n, flags);
1983 }
1984
1985 if (VCOM_DEBUG > 2)
1986 {
1987 if (size < 0)
1988 {
1989 int errno_val = errno;
1990 perror (func_str);
1991 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1992 "rv %d, errno = %d", getpid (), fd, fd,
1993 func_str, size, errno_val);
1994 errno = errno_val;
1995 }
1996 else
1997 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1998 getpid (), fd, fd, size, size);
1999 }
2000 return size;
2001}
2002
2003ssize_t
2004sendto (int fd, const void *buf, size_t n, int flags,
2005 __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
2006{
2007 ssize_t size;
2008 const char *func_str = __func__;
2009 u32 sid = vcom_sid_from_fd (fd);
2010
2011 if ((errno = -vcom_init ()))
2012 return -1;
2013
2014 if (sid != INVALID_SESSION_ID)
2015 {
2016 vppcom_endpt_t *ep = 0;
2017 vppcom_endpt_t _ep;
2018
2019 if (addr)
2020 {
2021 ep = &_ep;
2022 ep->vrf = VPPCOM_VRF_DEFAULT;
2023 switch (addr->sa_family)
2024 {
2025 case AF_INET:
2026 ep->is_ip4 = VPPCOM_IS_IP4;
2027 ep->ip =
2028 (uint8_t *) & ((const struct sockaddr_in *) addr)->sin_addr;
2029 ep->port =
2030 (uint16_t) ((const struct sockaddr_in *) addr)->sin_port;
2031 break;
2032
2033 case AF_INET6:
2034 ep->is_ip4 = VPPCOM_IS_IP6;
2035 ep->ip =
2036 (uint8_t *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
2037 ep->port =
2038 (uint16_t) ((const struct sockaddr_in6 *) addr)->sin6_port;
2039 break;
2040
2041 default:
2042 errno = EAFNOSUPPORT;
2043 size = -1;
2044 goto done;
2045 }
2046 }
2047
2048 func_str = "vppcom_session_sendto";
2049
2050 if (VCOM_DEBUG > 2)
2051 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2052 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2053 getpid (), fd, fd, func_str, sid, sid, buf, n,
2054 flags, ep);
2055
2056 size = vppcom_session_sendto (sid, (void *) buf, n, flags, ep);
2057 if (size < 0)
2058 {
2059 errno = -size;
2060 size = -1;
2061 }
2062 }
2063 else
2064 {
2065 func_str = "libc_sendto";
2066
2067 if (VCOM_DEBUG > 2)
2068 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2069 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2070 getpid (), fd, fd, func_str, buf, n, flags,
2071 addr, addr_len);
2072
2073 size = libc_sendto (fd, buf, n, flags, addr, addr_len);
2074 }
2075
2076done:
2077 if (VCOM_DEBUG > 2)
2078 {
2079 if (size < 0)
2080 {
2081 int errno_val = errno;
2082 perror (func_str);
2083 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2084 "rv %d, errno = %d", getpid (), fd, fd,
2085 func_str, size, errno_val);
2086 errno = errno_val;
2087 }
2088 else
2089 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2090 getpid (), fd, fd, size, size);
2091 }
2092 return size;
2093}
2094
2095ssize_t
2096recvfrom (int fd, void *__restrict buf, size_t n, int flags,
2097 __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
2098{
2099 ssize_t size;
2100 const char *func_str;
2101 u32 sid = vcom_sid_from_fd (fd);
2102
2103 if ((errno = -vcom_init ()))
2104 return -1;
2105
2106 if (sid != INVALID_SESSION_ID)
2107 {
2108 vppcom_endpt_t ep;
2109 u8 src_addr[sizeof (struct sockaddr_in6)];
2110
2111 func_str = "vppcom_session_recvfrom";
2112
2113 if (VCOM_DEBUG > 2)
2114 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2115 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2116 getpid (), fd, fd, func_str, sid, sid, buf, n,
2117 flags, &ep);
2118 if (addr)
2119 {
2120 ep.ip = src_addr;
2121 size = vppcom_session_recvfrom (sid, buf, n, flags, &ep);
2122
2123 if (size > 0)
2124 size = vcom_copy_ep_to_sockaddr (addr, addr_len, &ep);
2125 }
2126 else
2127 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
2128
2129 if (size < 0)
2130 {
2131 errno = -size;
2132 size = -1;
2133 }
2134 }
2135 else
2136 {
2137 func_str = "libc_recvfrom";
2138
2139 if (VCOM_DEBUG > 2)
2140 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2141 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2142 getpid (), fd, fd, func_str, buf, n, flags,
2143 addr, addr_len);
2144
2145 size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
2146 }
2147
2148 if (VCOM_DEBUG > 2)
2149 {
2150 if (size < 0)
2151 {
2152 int errno_val = errno;
2153 perror (func_str);
2154 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2155 "rv %d, errno = %d", getpid (), fd, fd,
2156 func_str, size, errno_val);
2157 errno = errno_val;
2158 }
2159 else
2160 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2161 getpid (), fd, fd, size, size);
2162 }
2163 return size;
2164}
2165
2166ssize_t
2167sendmsg (int fd, const struct msghdr * message, int flags)
2168{
2169 ssize_t size;
2170 const char *func_str;
2171 u32 sid = vcom_sid_from_fd (fd);
2172
2173 if ((errno = -vcom_init ()))
2174 return -1;
2175
2176 if (sid != INVALID_SESSION_ID)
2177 {
Dave Wallace8aaba562018-01-18 17:21:19 -05002178 func_str = __func__;
2179
Dave Wallace048b1d62018-01-03 22:24:41 -05002180 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2181 errno = ENOSYS;
2182 size = -1;
2183 }
2184 else
2185 {
2186 func_str = "libc_sendmsg";
2187
2188 if (VCOM_DEBUG > 2)
2189 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2190 "message %p, flags 0x%x",
2191 getpid (), fd, fd, func_str, message, flags);
2192
2193 size = libc_sendmsg (fd, message, flags);
2194 }
2195
2196 if (VCOM_DEBUG > 2)
2197 {
2198 if (size < 0)
2199 {
2200 int errno_val = errno;
2201 perror (func_str);
2202 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2203 "rv %d, errno = %d", getpid (), fd, fd,
2204 func_str, size, errno_val);
2205 errno = errno_val;
2206 }
2207 else
2208 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2209 getpid (), fd, fd, size, size);
2210 }
2211 return size;
2212}
2213
2214#ifdef USE_GNU
2215int
2216sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
2217{
2218 ssize_t size;
2219 const char *func_str;
2220 u32 sid = vcom_sid_from_fd (fd);
2221
2222 if ((errno = -vcom_init ()))
2223 return -1;
2224
2225 if (sid != INVALID_SESSION_ID)
2226 {
2227 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2228 errno = ENOSYS;
2229 size = -1;
2230 }
2231 else
2232 {
2233 func_str = "libc_sendmmsg";
2234
2235 if (VCOM_DEBUG > 2)
2236 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2237 "vmessages %p, vlen %u, flags 0x%x",
2238 getpid (), fd, fd, func_str, vmessages, vlen, flags);
2239
2240 size = libc_sendmmsg (fd, vmessages, vlen, flags);
2241 }
2242
2243 if (VCOM_DEBUG > 2)
2244 {
2245 if (size < 0)
2246 {
2247 int errno_val = errno;
2248 perror (func_str);
2249 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2250 "rv %d, errno = %d", getpid (), fd, fd,
2251 func_str, size, errno_val);
2252 errno = errno_val;
2253 }
2254 else
2255 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2256 getpid (), fd, fd, size, size);
2257 }
2258 return size;
2259}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002260#endif
2261
Dave Wallace048b1d62018-01-03 22:24:41 -05002262ssize_t
2263recvmsg (int fd, struct msghdr * message, int flags)
2264{
2265 ssize_t size;
2266 const char *func_str;
2267 u32 sid = vcom_sid_from_fd (fd);
2268
2269 if ((errno = -vcom_init ()))
2270 return -1;
2271
2272 if (sid != INVALID_SESSION_ID)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002273 {
Dave Wallace8aaba562018-01-18 17:21:19 -05002274 func_str = __func__;
2275
Dave Wallace048b1d62018-01-03 22:24:41 -05002276 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2277 errno = ENOSYS;
2278 size = -1;
2279 }
2280 else
2281 {
2282 func_str = "libc_recvmsg";
2283
2284 if (VCOM_DEBUG > 2)
2285 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2286 "message %p, flags 0x%x",
2287 getpid (), fd, fd, func_str, message, flags);
2288
2289 size = libc_recvmsg (fd, message, flags);
2290 }
2291
2292 if (VCOM_DEBUG > 2)
2293 {
2294 if (size < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002295 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002296 int errno_val = errno;
2297 perror (func_str);
2298 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2299 "rv %d, errno = %d", getpid (), fd, fd,
2300 func_str, size, errno_val);
2301 errno = errno_val;
2302 }
2303 else
2304 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2305 getpid (), fd, fd, size, size);
2306 }
2307 return size;
2308}
2309
2310#ifdef USE_GNU
2311int
2312recvmmsg (int fd, struct mmsghdr *vmessages,
2313 unsigned int vlen, int flags, struct timespec *tmo)
2314{
2315 ssize_t size;
2316 const char *func_str;
2317 u32 sid = vcom_sid_from_fd (fd);
2318
2319 if ((errno = -vcom_init ()))
2320 return -1;
2321
2322 if (sid != INVALID_SESSION_ID)
2323 {
2324 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2325 errno = ENOSYS;
2326 size = -1;
2327 }
2328 else
2329 {
2330 func_str = "libc_recvmmsg";
2331
2332 if (VCOM_DEBUG > 2)
2333 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2334 "vmessages %p, vlen %u, flags 0x%x, tmo %p",
2335 getpid (), fd, fd, func_str, vmessages, vlen,
2336 flags, tmo);
2337
2338 size = libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
2339 }
2340
2341 if (VCOM_DEBUG > 2)
2342 {
2343 if (size < 0)
2344 {
2345 int errno_val = errno;
2346 perror (func_str);
2347 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2348 "rv %d, errno = %d", getpid (), fd, fd,
2349 func_str, size, errno_val);
2350 errno = errno_val;
2351 }
2352 else
2353 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2354 getpid (), fd, fd, size, size);
2355 }
2356 return size;
2357}
2358#endif
2359
2360int
2361getsockopt (int fd, int level, int optname,
2362 void *__restrict optval, socklen_t * __restrict optlen)
2363{
2364 int rv;
2365 const char *func_str = __func__;
2366 u32 sid = vcom_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -05002367 u32 buflen = optlen ? (u32) * optlen : 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05002368
2369 if ((errno = -vcom_init ()))
2370 return -1;
2371
2372 if (sid != INVALID_SESSION_ID)
2373 {
2374 rv = -EOPNOTSUPP;
2375
2376 switch (level)
2377 {
2378 case SOL_TCP:
2379 switch (optname)
2380 {
2381 case TCP_NODELAY:
2382 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_NODELAY]";
2383 if (VCOM_DEBUG > 1)
2384 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2385 "sid %u (0x%x)",
2386 getpid (), fd, fd, func_str, sid, sid);
2387 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_NODELAY,
2388 optval, optlen);
2389 break;
2390 case TCP_MAXSEG:
2391 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_USER_MSS]";
2392 if (VCOM_DEBUG > 1)
2393 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2394 "sid %u (0x%x)",
2395 getpid (), fd, fd, func_str, sid, sid);
2396 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_USER_MSS,
2397 optval, optlen);
2398 break;
2399 case TCP_KEEPIDLE:
2400 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPIDLE]";
2401 if (VCOM_DEBUG > 1)
2402 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2403 "sid %u (0x%x)",
2404 getpid (), fd, fd, func_str, sid, sid);
2405 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
2406 optval, optlen);
2407 break;
2408 case TCP_KEEPINTVL:
2409 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPINTVL]";
2410 if (VCOM_DEBUG > 1)
2411 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2412 "sid %u (0x%x), SOL_TCP",
2413 getpid (), fd, fd, func_str, sid, sid);
2414 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
2415 optval, optlen);
2416 break;
2417 case TCP_INFO:
2418 if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
2419 {
2420 if (VCOM_DEBUG > 1)
2421 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x), "
2422 "SOL_TCP, TCP_INFO, optval %p, "
2423 "optlen %d: #LDP-NOP#",
2424 getpid (), fd, fd, sid, sid,
2425 optval, *optlen);
2426 memset (optval, 0, *optlen);
2427 rv = VPPCOM_OK;
2428 }
2429 else
2430 rv = -EFAULT;
2431 break;
2432 default:
2433 if (VCOM_DEBUG > 1)
2434 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2435 "sid %u (0x%x), SOL_TCP, "
2436 "optname %d unsupported!",
2437 getpid (), fd, fd, func_str, sid, sid, optname);
2438 break;
2439 }
2440 break;
2441 case SOL_IPV6:
2442 switch (optname)
2443 {
2444 case IPV6_V6ONLY:
2445 func_str = "vppcom_session_attr[SOL_IPV6,GET_V6ONLY]";
2446 if (VCOM_DEBUG > 1)
2447 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2448 "sid %u (0x%x)",
2449 getpid (), fd, fd, func_str, sid, sid);
2450 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_V6ONLY,
2451 optval, optlen);
2452 break;
2453 default:
2454 if (VCOM_DEBUG > 1)
2455 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2456 "sid %u (0x%x), SOL_IPV6, "
2457 "optname %d unsupported!",
2458 getpid (), fd, fd, func_str, sid, sid, optname);
2459 break;
2460 }
2461 break;
2462 case SOL_SOCKET:
2463 switch (optname)
2464 {
2465 case SO_ACCEPTCONN:
2466 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ACCEPTCONN]";
2467 if (VCOM_DEBUG > 1)
2468 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2469 "sid %u (0x%x)",
2470 getpid (), fd, fd, func_str, sid, sid);
2471 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LISTEN,
2472 optval, optlen);
2473 break;
2474 case SO_KEEPALIVE:
2475 func_str = "vppcom_session_attr[SOL_SOCKET,GET_KEEPALIVE]";
2476 if (VCOM_DEBUG > 1)
2477 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2478 "sid %u (0x%x)",
2479 getpid (), fd, fd, func_str, sid, sid);
2480 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_KEEPALIVE,
2481 optval, optlen);
2482 break;
2483 case SO_PROTOCOL:
2484 func_str = "vppcom_session_attr[SOL_SOCKET,GET_PROTOCOL]";
2485 if (VCOM_DEBUG > 1)
2486 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2487 "sid %u (0x%x)",
2488 getpid (), fd, fd, func_str, sid, sid);
2489 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PROTOCOL,
2490 optval, optlen);
2491 *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
2492 break;
2493 case SO_SNDBUF:
2494 func_str = "vppcom_session_attr[SOL_SOCKET,GET_TX_FIFO_LEN]";
2495 if (VCOM_DEBUG > 1)
2496 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2497 "sid %u (0x%x), optlen %d",
2498 getpid (), fd, fd, func_str, sid, sid, buflen);
2499 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TX_FIFO_LEN,
2500 optval, optlen);
2501 break;
2502 case SO_RCVBUF:
2503 func_str = "vppcom_session_attr[SOL_SOCKET,GET_RX_FIFO_LEN]";
2504 if (VCOM_DEBUG > 1)
2505 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2506 "sid %u (0x%x), optlen %d",
Dave Wallaceb4cd4ff2018-01-19 12:17:08 -05002507 getpid (), fd, fd, func_str, sid, sid, buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002508 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_RX_FIFO_LEN,
2509 optval, optlen);
2510 break;
2511 case SO_REUSEADDR:
2512 func_str = "vppcom_session_attr[SOL_SOCKET,GET_REUSEADDR]";
2513 if (VCOM_DEBUG > 1)
2514 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2515 "sid %u (0x%x)",
2516 getpid (), fd, fd, func_str, sid, sid);
2517 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REUSEADDR,
2518 optval, optlen);
2519 break;
2520 case SO_BROADCAST:
2521 func_str = "vppcom_session_attr[SOL_SOCKET,GET_BROADCAST]";
2522 if (VCOM_DEBUG > 1)
2523 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2524 "sid %u (0x%x)",
2525 getpid (), fd, fd, func_str, sid, sid);
2526 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_BROADCAST,
2527 optval, optlen);
2528 break;
2529 case SO_ERROR:
2530 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ERROR]";
2531 if (VCOM_DEBUG > 1)
2532 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2533 "sid %u (0x%x)",
2534 getpid (), fd, fd, func_str, sid, sid);
2535 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_ERROR,
2536 optval, optlen);
2537 break;
2538 default:
2539 if (VCOM_DEBUG > 1)
2540 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2541 "sid %u (0x%x), SOL_SOCKET, "
2542 "optname %d unsupported!",
2543 getpid (), fd, fd, func_str, sid, sid, optname);
2544 break;
2545 }
2546 break;
2547 default:
2548 break;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002549 }
2550
Dave Wallace048b1d62018-01-03 22:24:41 -05002551 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002552 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002553 errno = -rv;
2554 rv = -1;
2555 }
2556 }
2557 else
2558 {
2559 func_str = "libc_getsockopt";
2560
2561 if (VCOM_DEBUG > 1)
2562 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2563 "optname %d, optval %p, optlen %d",
2564 getpid (), fd, fd, func_str, level, optname,
2565 optval, optlen);
2566
2567 rv = libc_getsockopt (fd, level, optname, optval, optlen);
2568 }
2569
2570 if (VCOM_DEBUG > 1)
2571 {
2572 if (rv < 0)
2573 {
2574 int errno_val = errno;
2575 perror (func_str);
2576 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2577 "rv %d, errno = %d", getpid (), fd, fd,
2578 func_str, rv, errno_val);
2579 errno = errno_val;
2580 }
2581 else
2582 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2583 getpid (), fd, fd, rv, rv);
2584 }
2585 return rv;
2586}
2587
2588int
2589setsockopt (int fd, int level, int optname,
2590 const void *optval, socklen_t optlen)
2591{
2592 int rv;
2593 const char *func_str = __func__;
2594 u32 sid = vcom_sid_from_fd (fd);
2595
2596 if ((errno = -vcom_init ()))
2597 return -1;
2598
2599 if (sid != INVALID_SESSION_ID)
2600 {
2601 rv = -EOPNOTSUPP;
2602
2603 switch (level)
2604 {
2605 case SOL_TCP:
2606 switch (optname)
2607 {
2608 case TCP_NODELAY:
2609 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_NODELAY]";
2610 if (VCOM_DEBUG > 1)
2611 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2612 "sid %u (0x%x)",
2613 getpid (), fd, fd, func_str, sid, sid);
2614 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_NODELAY,
2615 (void *) optval, &optlen);
2616 break;
2617 case TCP_MAXSEG:
2618 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_USER_MSS]";
2619 if (VCOM_DEBUG > 1)
2620 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2621 "sid %u (0x%x)",
2622 getpid (), fd, fd, func_str, sid, sid);
2623 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_USER_MSS,
2624 (void *) optval, &optlen);
2625 break;
2626 case TCP_KEEPIDLE:
2627 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPIDLE]";
2628 if (VCOM_DEBUG > 1)
2629 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2630 "sid %u (0x%x)",
2631 getpid (), fd, fd, func_str, sid, sid);
2632 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
2633 (void *) optval, &optlen);
2634 break;
2635 case TCP_KEEPINTVL:
2636 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPINTVL]";
2637 if (VCOM_DEBUG > 1)
2638 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2639 "sid %u (0x%x), SOL_TCP",
2640 getpid (), fd, fd, func_str, sid, sid);
2641 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
2642 (void *) optval, &optlen);
2643 break;
2644 default:
2645 if (VCOM_DEBUG > 1)
2646 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2647 "sid %u (0x%x), SOL_TCP, "
2648 "optname %d unsupported!",
2649 getpid (), fd, fd, func_str, sid, sid, optname);
2650 break;
2651 }
2652 break;
2653 case SOL_IPV6:
2654 switch (optname)
2655 {
2656 case IPV6_V6ONLY:
2657 func_str = "vppcom_session_attr[SOL_IPV6,SET_V6ONLY]";
2658 if (VCOM_DEBUG > 1)
2659 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2660 "sid %u (0x%x)",
2661 getpid (), fd, fd, func_str, sid, sid);
2662 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_V6ONLY,
2663 (void *) optval, &optlen);
2664 break;
2665 default:
2666 if (VCOM_DEBUG > 1)
2667 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2668 "sid %u (0x%x), SOL_IPV6, "
2669 "optname %d unsupported!",
2670 getpid (), fd, fd, func_str, sid, sid, optname);
2671 break;
2672 }
2673 break;
2674 case SOL_SOCKET:
2675 switch (optname)
2676 {
2677 case SO_KEEPALIVE:
2678 func_str = "vppcom_session_attr[SOL_SOCKET,SET_KEEPALIVE]";
2679 if (VCOM_DEBUG > 1)
2680 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2681 "sid %u (0x%x)",
2682 getpid (), fd, fd, func_str, sid, sid);
2683 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_KEEPALIVE,
2684 (void *) optval, &optlen);
2685 break;
2686 case SO_REUSEADDR:
2687 func_str = "vppcom_session_attr[SOL_SOCKET,SET_REUSEADDR]";
2688 if (VCOM_DEBUG > 1)
2689 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2690 "sid %u (0x%x)",
2691 getpid (), fd, fd, func_str, sid, sid);
2692 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_REUSEADDR,
2693 (void *) optval, &optlen);
2694 break;
2695 case SO_BROADCAST:
2696 func_str = "vppcom_session_attr[SOL_SOCKET,SET_BROADCAST]";
2697 if (VCOM_DEBUG > 1)
2698 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2699 "sid %u (0x%x)",
2700 getpid (), fd, fd, func_str, sid, sid);
2701 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_BROADCAST,
2702 (void *) optval, &optlen);
2703 break;
2704 default:
2705 if (VCOM_DEBUG > 1)
2706 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2707 "sid %u (0x%x), SOL_SOCKET, "
2708 "optname %d unsupported!",
2709 getpid (), fd, fd, func_str, sid, sid, optname);
2710 break;
2711 }
2712 break;
2713 default:
2714 break;
2715 }
2716
2717 if (rv != VPPCOM_OK)
2718 {
2719 errno = -rv;
2720 rv = -1;
2721 }
2722 }
2723 else
2724 {
2725 func_str = "libc_setsockopt";
2726
2727 if (VCOM_DEBUG > 1)
2728 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2729 "optname %d, optval %p, optlen %d",
2730 getpid (), fd, fd, func_str, level, optname,
2731 optval, optlen);
2732
2733 rv = libc_setsockopt (fd, level, optname, optval, optlen);
2734 }
2735
2736 if (VCOM_DEBUG > 1)
2737 {
2738 if (rv < 0)
2739 {
2740 int errno_val = errno;
2741 perror (func_str);
2742 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2743 "rv %d, errno = %d", getpid (), fd, fd,
2744 func_str, rv, errno_val);
2745 errno = errno_val;
2746 }
2747 else
2748 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2749 getpid (), fd, fd, rv, rv);
2750 }
2751 return rv;
2752}
2753
2754int
2755listen (int fd, int n)
2756{
2757 int rv;
2758 const char *func_str;
2759 u32 sid = vcom_sid_from_fd (fd);
2760
2761 if ((errno = -vcom_init ()))
2762 return -1;
2763
2764 if (sid != INVALID_SESSION_ID)
2765 {
2766 func_str = "vppcom_session_listen";
2767
2768 if (VCOM_DEBUG > 0)
2769 clib_warning
2770 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), n %d",
2771 getpid (), fd, fd, func_str, sid, sid, n);
2772
2773 rv = vppcom_session_listen (sid, n);
2774 if (rv != VPPCOM_OK)
2775 {
2776 errno = -rv;
2777 rv = -1;
2778 }
2779 }
2780 else
2781 {
2782 func_str = "libc_listen";
2783
2784 if (VCOM_DEBUG > 0)
2785 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): n %d",
2786 getpid (), fd, fd, func_str, n);
2787
2788 rv = libc_listen (fd, n);
2789 }
2790
2791 if (VCOM_DEBUG > 0)
2792 {
2793 if (rv < 0)
2794 {
2795 int errno_val = errno;
2796 perror (func_str);
2797 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2798 "rv %d, errno = %d", getpid (), fd, fd,
2799 func_str, rv, errno_val);
2800 errno = errno_val;
2801 }
2802 else
2803 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2804 getpid (), fd, fd, rv, rv);
2805 }
2806 return rv;
2807}
2808
2809static inline int
2810vcom_accept4 (int listen_fd, __SOCKADDR_ARG addr,
2811 socklen_t * __restrict addr_len, int flags)
2812{
2813 int rv;
2814 const char *func_str;
2815 u32 listen_sid = vcom_sid_from_fd (listen_fd);
2816 int accept_sid;
2817
2818 if ((errno = -vcom_init ()))
2819 return -1;
2820
2821 if (listen_sid != INVALID_SESSION_ID)
2822 {
2823 vppcom_endpt_t ep;
2824 u8 src_addr[sizeof (struct sockaddr_in6)];
Dave Wallace8aaba562018-01-18 17:21:19 -05002825 memset (&ep, 0, sizeof (ep));
Dave Wallace048b1d62018-01-03 22:24:41 -05002826 ep.ip = src_addr;
2827
2828 func_str = "vppcom_session_accept";
2829
2830 if (VCOM_DEBUG > 0)
2831 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2832 "listen sid %u (0x%x), ep %p, flags 0x%x",
2833 getpid (), listen_fd, listen_fd, func_str,
2834 listen_sid, listen_sid, ep, flags);
2835
2836 accept_sid = vppcom_session_accept (listen_sid, &ep, flags);
2837 if (accept_sid < 0)
2838 {
2839 errno = -accept_sid;
2840 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002841 }
2842 else
2843 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002844 rv = vcom_copy_ep_to_sockaddr (addr, addr_len, &ep);
2845 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002846 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002847 (void) vppcom_session_close ((u32) accept_sid);
2848 errno = -rv;
2849 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002850 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002851 else
2852 {
2853 func_str = "vcom_fd_from_sid";
2854 if (VCOM_DEBUG > 0)
2855 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2856 "accept sid %u (0x%x), ep %p, flags 0x%x",
2857 getpid (), listen_fd, listen_fd,
2858 func_str, accept_sid, accept_sid, ep, flags);
2859 rv = vcom_fd_from_sid ((u32) accept_sid);
2860 if (rv < 0)
2861 {
2862 (void) vppcom_session_close ((u32) accept_sid);
2863 errno = -rv;
2864 rv = -1;
2865 }
2866 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002867 }
2868 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002869 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002870 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002871 func_str = "libc_accept4";
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002872
Dave Wallace048b1d62018-01-03 22:24:41 -05002873 if (VCOM_DEBUG > 0)
2874 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2875 "addr %p, addr_len %p, flags 0x%x",
2876 getpid (), listen_fd, listen_fd, func_str,
2877 addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002878
Dave Wallace048b1d62018-01-03 22:24:41 -05002879 rv = libc_accept4 (listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002880 }
2881
Dave Wallace048b1d62018-01-03 22:24:41 -05002882 if (VCOM_DEBUG > 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002883 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002884 if (rv < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002885 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002886 int errno_val = errno;
2887 perror (func_str);
2888 clib_warning ("LDP<%d>: ERROR: listen fd %d (0x%x): %s() failed! "
2889 "rv %d, errno = %d", getpid (), listen_fd,
2890 listen_fd, func_str, rv, errno_val);
2891 errno = errno_val;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002892 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002893 else
2894 clib_warning ("LDP<%d>: listen fd %d (0x%x): returning %d (0x%x)",
2895 getpid (), listen_fd, listen_fd, rv, rv);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002896 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002897 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002898}
2899
Dave Wallace048b1d62018-01-03 22:24:41 -05002900int
2901accept4 (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len,
2902 int flags)
2903{
2904 return vcom_accept4 (fd, addr, addr_len, flags);
2905}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002906
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002907int
Dave Wallace048b1d62018-01-03 22:24:41 -05002908accept (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002909{
Dave Wallace048b1d62018-01-03 22:24:41 -05002910 return vcom_accept4 (fd, addr, addr_len, 0);
2911}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002912
Dave Wallace048b1d62018-01-03 22:24:41 -05002913int
2914shutdown (int fd, int how)
2915{
2916 int rv;
2917 const char *func_str;
2918 u32 sid = vcom_sid_from_fd (fd);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002919
Dave Wallace048b1d62018-01-03 22:24:41 -05002920 if ((errno = -vcom_init ()))
2921 return -1;
2922
2923 if (sid != INVALID_SESSION_ID)
2924 {
Dave Wallace8aaba562018-01-18 17:21:19 -05002925 func_str = __func__;
2926
Dave Wallace048b1d62018-01-03 22:24:41 -05002927 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2928 errno = ENOSYS;
2929 rv = -1;
2930 }
2931 else
2932 {
2933 func_str = "libc_shutdown";
2934
2935 if (VCOM_DEBUG > 1)
2936 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): how %d",
2937 getpid (), fd, fd, func_str, how);
2938
2939 rv = libc_shutdown (fd, how);
2940 }
2941
2942 if (VCOM_DEBUG > 1)
2943 {
2944 if (rv < 0)
2945 {
2946 int errno_val = errno;
2947 perror (func_str);
2948 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2949 "rv %d, errno = %d", getpid (), fd, fd,
2950 func_str, rv, errno_val);
2951 errno = errno_val;
2952 }
2953 else
2954 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2955 getpid (), fd, fd, rv, rv);
2956 }
2957 return rv;
2958}
2959
2960int
2961epoll_create1 (int flags)
2962{
2963 const char *func_str;
2964 int rv;
2965
2966 if ((errno = -vcom_init ()))
2967 return -1;
2968
2969 func_str = "vppcom_epoll_create";
2970
2971 if (VCOM_DEBUG > 1)
2972 clib_warning ("LDP<%d>: calling %s()", getpid (), func_str);
2973
2974 rv = vppcom_epoll_create ();
2975
2976 if (PREDICT_FALSE (rv < 0))
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002977 {
2978 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002979 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002980 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002981 else
2982 rv = vcom_fd_from_sid ((u32) rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002983
Dave Wallace048b1d62018-01-03 22:24:41 -05002984 if (VCOM_DEBUG > 1)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002985 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002986 if (rv < 0)
2987 {
2988 int errno_val = errno;
2989 perror (func_str);
2990 clib_warning ("LDP<%d>: ERROR: %s() failed! "
2991 "rv %d, errno = %d",
2992 getpid (), func_str, rv, errno_val);
2993 errno = errno_val;
2994 }
2995 else
2996 clib_warning ("LDP<%d>: returning epfd %d (0x%x)", getpid (), rv, rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002997 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002998 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002999}
3000
3001int
Dave Wallace048b1d62018-01-03 22:24:41 -05003002epoll_create (int size)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003003{
Dave Wallace048b1d62018-01-03 22:24:41 -05003004 return epoll_create1 (0);
3005}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003006
Dave Wallace048b1d62018-01-03 22:24:41 -05003007int
3008epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
3009{
3010 int rv;
3011 const char *func_str;
3012 u32 vep_idx = vcom_sid_from_fd (epfd);
3013
3014 if ((errno = -vcom_init ()))
3015 return -1;
3016
3017 if (vep_idx != INVALID_SESSION_ID)
3018 {
3019 u32 sid = vcom_sid_from_fd (fd);
3020
3021 if (sid != INVALID_SESSION_ID)
3022 {
3023 func_str = "vppcom_epoll_create";
3024
3025 if (VCOM_DEBUG > 1)
3026 clib_warning ("LDP<%d>: epfd %d (0x%x): calling %s(): "
3027 "vep_idx %d (0x%x), op %d, sid %u (0x%x), event %p",
3028 getpid (), epfd, epfd, func_str, vep_idx, vep_idx,
3029 sid, sid, event);
3030
3031 rv = vppcom_epoll_ctl (vep_idx, op, sid, event);
3032 if (rv != VPPCOM_OK)
3033 {
3034 errno = -rv;
3035 rv = -1;
3036 }
3037 }
3038 else
3039 {
3040 int epfd;
3041 u32 size = sizeof (epfd);
3042
3043 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
3044 epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD,
3045 0, 0);
3046 if (!epfd)
3047 {
3048 func_str = "libc_epoll_create1";
3049
3050 if (VCOM_DEBUG > 1)
3051 clib_warning ("LDP<%d>: calling %s(): EPOLL_CLOEXEC",
3052 getpid (), func_str);
3053
3054 epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
3055 if (epfd < 0)
3056 {
3057 rv = epfd;
3058 goto done;
3059 }
3060
3061 func_str = "vppcom_session_attr[SET_LIBC_EPFD]";
3062 rv = vppcom_session_attr (vep_idx, VPPCOM_ATTR_SET_LIBC_EPFD,
3063 &epfd, &size);
3064 if (rv < 0)
3065 {
3066 errno = -rv;
3067 rv = -1;
3068 goto done;
3069 }
3070 }
3071 else if (PREDICT_FALSE (epfd < 0))
3072 {
3073 errno = -epfd;
3074 rv = -1;
3075 goto done;
3076 }
3077
3078 rv = libc_epoll_ctl (epfd, op, fd, event);
3079 }
3080 }
3081 else
3082 {
3083 func_str = "libc_epoll_ctl";
3084
3085 if (VCOM_DEBUG > 1)
3086 clib_warning ("LDP<%d>: epfd %d (0x%x): calling %s(): "
3087 "op %d, fd %d (0x%x), event %p",
3088 getpid (), epfd, epfd, func_str, op, fd, fd, event);
3089
3090 rv = libc_epoll_ctl (epfd, op, fd, event);
3091 }
3092
3093done:
3094 if (VCOM_DEBUG > 1)
3095 {
3096 if (rv < 0)
3097 {
3098 int errno_val = errno;
3099 perror (func_str);
3100 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
3101 "rv %d, errno = %d", getpid (), fd, fd,
3102 func_str, rv, errno_val);
3103 errno = errno_val;
3104 }
3105 else
3106 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
3107 getpid (), fd, fd, rv, rv);
3108 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003109 return rv;
3110}
Dave Wallace048b1d62018-01-03 22:24:41 -05003111
3112static inline int
3113vcom_epoll_pwait (int epfd, struct epoll_event *events,
3114 int maxevents, int timeout, const sigset_t * sigmask)
3115{
3116 const char *func_str;
Dave Wallace8aaba562018-01-18 17:21:19 -05003117 int rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003118 double time_to_wait = (double) 0;
3119 double time_out, now = 0;
3120 u32 vep_idx = vcom_sid_from_fd (epfd);
3121 int libc_epfd;
3122
3123 if ((errno = -vcom_init ()))
3124 return -1;
3125
3126 if (PREDICT_FALSE (!events || (timeout < -1)))
3127 {
3128 errno = EFAULT;
3129 return -1;
3130 }
3131
3132 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
3133 {
3134 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): bad vep_idx %d (0x%x)!",
3135 getpid (), epfd, epfd, vep_idx, vep_idx);
3136 errno = EBADFD;
3137 return -1;
3138 }
3139
3140 time_to_wait = ((timeout >= 0) ? (double) timeout / (double) 1000 : 0);
3141 time_out = clib_time_now (&vcom->clib_time) + time_to_wait;
3142
3143 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
3144 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
3145 if (PREDICT_FALSE (libc_epfd < 0))
3146 {
3147 errno = -libc_epfd;
3148 rv = -1;
3149 goto done;
3150 }
3151
3152 if (VCOM_DEBUG > 2)
3153 clib_warning ("LDP<%d>: epfd %d (0x%x): vep_idx %d (0x%x), "
3154 "libc_epfd %d (0x%x), events %p, maxevents %d, "
3155 "timeout %d, sigmask %p", getpid (), epfd, epfd,
3156 vep_idx, vep_idx, libc_epfd, libc_epfd, events,
3157 maxevents, timeout, sigmask);
3158 do
3159 {
3160 if (!vcom->epoll_wait_vcl)
3161 {
3162 func_str = "vppcom_epoll_wait";
3163
3164 if (VCOM_DEBUG > 3)
3165 clib_warning ("LDP<%d>: epfd %d (0x%x): calling %s(): "
3166 "vep_idx %d (0x%x), events %p, maxevents %d",
3167 getpid (), epfd, epfd, func_str,
3168 vep_idx, vep_idx, events, maxevents);
3169
3170 rv = vppcom_epoll_wait (vep_idx, events, maxevents, 0);
3171 if (rv > 0)
3172 {
3173 vcom->epoll_wait_vcl = 1;
3174 goto done;
3175 }
3176 else if (rv < 0)
3177 {
3178 errno = -rv;
3179 rv = -1;
3180 goto done;
3181 }
3182 }
3183 else
3184 vcom->epoll_wait_vcl = 0;
3185
3186 if (libc_epfd > 0)
3187 {
3188 func_str = "libc_epoll_pwait";
3189
3190 if (VCOM_DEBUG > 3)
3191 clib_warning ("LDP<%d>: epfd %d (0x%x): calling %s(): "
3192 "libc_epfd %d (0x%x), events %p, "
3193 "maxevents %d, sigmask %p",
3194 getpid (), epfd, epfd, func_str,
3195 libc_epfd, libc_epfd, events, maxevents, sigmask);
3196
3197 rv = libc_epoll_pwait (epfd, events, maxevents, 1, sigmask);
3198 if (rv != 0)
3199 goto done;
3200 }
3201
3202 if (timeout != -1)
3203 now = clib_time_now (&vcom->clib_time);
3204 }
3205 while (now < time_out);
3206
3207done:
3208 if (VCOM_DEBUG > 3)
3209 {
3210 if (rv < 0)
3211 {
3212 int errno_val = errno;
3213 perror (func_str);
3214 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): %s() failed! "
3215 "rv %d, errno = %d", getpid (), epfd, epfd,
3216 func_str, rv, errno_val);
3217 errno = errno_val;
3218 }
3219 else
3220 clib_warning ("LDP<%d>: epfd %d (0x%x): returning %d (0x%x)",
3221 getpid (), epfd, epfd, rv, rv);
3222 }
3223 return rv;
3224}
3225
3226int
3227epoll_pwait (int epfd, struct epoll_event *events,
3228 int maxevents, int timeout, const sigset_t * sigmask)
3229{
3230 return vcom_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
3231}
3232
3233int
3234epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
3235{
3236 return vcom_epoll_pwait (epfd, events, maxevents, timeout, NULL);
3237}
3238
3239int
3240poll (struct pollfd *fds, nfds_t nfds, int timeout)
3241{
3242 const char *func_str = __func__;
3243 int rv, i, n_libc_fds, n_revents;
3244 u32 sid;
3245 vcl_poll_t *vp;
3246 double wait_for_time;
3247
3248 if (VCOM_DEBUG > 3)
3249 clib_warning ("LDP<%d>: fds %p, nfds %d, timeout %d",
3250 getpid (), fds, nfds, timeout);
3251
3252 if (timeout >= 0)
3253 wait_for_time = (f64) timeout / 1000;
3254 else
3255 wait_for_time = -1;
3256
3257 n_libc_fds = 0;
3258 for (i = 0; i < nfds; i++)
3259 {
3260 if (fds[i].fd >= 0)
3261 {
3262 if (VCOM_DEBUG > 3)
3263 clib_warning ("LDP<%d>: fds[%d].fd %d (0x%0x), .events = 0x%x, "
3264 ".revents = 0x%x", getpid (), i, fds[i].fd,
3265 fds[i].fd, fds[i].events, fds[i].revents);
3266
3267 sid = vcom_sid_from_fd (fds[i].fd);
3268 if (sid != INVALID_SESSION_ID)
3269 {
3270 fds[i].fd = -fds[i].fd;
3271 vec_add2 (vcom->vcl_poll, vp, 1);
3272 vp->fds_ndx = i;
3273 vp->sid = sid;
3274 vp->events = fds[i].events;
3275#ifdef __USE_XOPEN2K
3276 if (fds[i].events & POLLRDNORM)
3277 vp->events |= POLLIN;
3278 if (fds[i].events & POLLWRNORM)
3279 vp->events |= POLLOUT;
3280#endif
3281 vp->revents = &fds[i].revents;
3282 }
3283 else
3284 n_libc_fds++;
3285 }
3286 }
3287
3288 n_revents = 0;
3289 do
3290 {
3291 if (vec_len (vcom->vcl_poll))
3292 {
3293 func_str = "vppcom_poll";
3294
3295 if (VCOM_DEBUG > 3)
3296 clib_warning ("LDP<%d>: calling %s(): "
3297 "vcl_poll %p, n_sids %u (0x%x): "
3298 "n_libc_fds %u",
3299 getpid (), func_str, vcom->vcl_poll,
3300 vec_len (vcom->vcl_poll), vec_len (vcom->vcl_poll),
3301 n_libc_fds);
3302
3303 rv = vppcom_poll (vcom->vcl_poll, vec_len (vcom->vcl_poll), 0);
3304 if (rv < 0)
3305 {
3306 errno = -rv;
3307 rv = -1;
3308 goto done;
3309 }
3310 else
3311 n_revents += rv;
3312 }
3313
3314 if (n_libc_fds)
3315 {
3316 func_str = "libc_poll";
3317
3318 if (VCOM_DEBUG > 3)
3319 clib_warning ("LDP<%d>: calling %s(): fds %p, nfds %u: n_sids %u",
3320 getpid (), fds, nfds, vec_len (vcom->vcl_poll));
3321
3322 rv = libc_poll (fds, nfds, 0);
3323 if (rv < 0)
3324 goto done;
3325 else
3326 n_revents += rv;
3327 }
3328
3329 if (n_revents)
3330 {
3331 rv = n_revents;
3332 goto done;
3333 }
3334 }
3335 while ((wait_for_time == -1) ||
3336 (clib_time_now (&vcom->clib_time) < wait_for_time));
3337 rv = 0;
3338
3339done:
3340 vec_foreach (vp, vcom->vcl_poll)
3341 {
3342 fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd;
3343#ifdef __USE_XOPEN2K
3344 if ((fds[vp->fds_ndx].revents & POLLIN) &&
3345 (fds[vp->fds_ndx].events & POLLRDNORM))
3346 fds[vp->fds_ndx].revents |= POLLRDNORM;
3347 if ((fds[vp->fds_ndx].revents & POLLOUT) &&
3348 (fds[vp->fds_ndx].events & POLLWRNORM))
3349 fds[vp->fds_ndx].revents |= POLLWRNORM;
3350#endif
3351 }
3352 vec_reset_length (vcom->vcl_poll);
3353
3354 if (VCOM_DEBUG > 3)
3355 {
3356 if (rv < 0)
3357 {
3358 int errno_val = errno;
3359 perror (func_str);
3360 clib_warning ("LDP<%d>: ERROR: %s() failed! "
3361 "rv %d, errno = %d", getpid (),
3362 func_str, rv, errno_val);
3363 errno = errno_val;
3364 }
3365 else
3366 {
3367 clib_warning ("LDP<%d>: returning %d (0x%x): n_sids %u, "
3368 "n_libc_fds %d", getpid (), rv, rv,
3369 vec_len (vcom->vcl_poll), n_libc_fds);
3370
3371 for (i = 0; i < nfds; i++)
3372 {
3373 if (fds[i].fd >= 0)
3374 {
3375 if (VCOM_DEBUG > 3)
3376 clib_warning ("LDP<%d>: fds[%d].fd %d (0x%0x), "
3377 ".events = 0x%x, .revents = 0x%x",
3378 getpid (), i, fds[i].fd, fds[i].fd,
3379 fds[i].events, fds[i].revents);
3380 }
3381 }
3382 }
3383 }
3384
3385 return rv;
3386}
3387
3388#ifdef USE_GNU
3389int
3390ppoll (struct pollfd *fds, nfds_t nfds,
3391 const struct timespec *timeout, const sigset_t * sigmask)
3392{
3393 if ((errno = -vcom_init ()))
3394 return -1;
3395
3396 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
3397 errno = ENOSYS;
3398
3399
3400 return -1;
3401}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003402#endif
3403
3404void CONSTRUCTOR_ATTRIBUTE vcom_constructor (void);
3405
3406void DESTRUCTOR_ATTRIBUTE vcom_destructor (void);
3407
Dave Wallace048b1d62018-01-03 22:24:41 -05003408/*
3409 * This function is called when the library is loaded
3410 */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003411void
3412vcom_constructor (void)
3413{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003414 swrap_constructor ();
3415 if (vcom_init () != 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003416 fprintf (stderr, "\nLDP<%d>: ERROR: vcom_constructor: failed!\n",
3417 getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003418 else
Dave Wallace048b1d62018-01-03 22:24:41 -05003419 clib_warning ("LDP<%d>: VCOM constructor: done!\n", getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003420}
3421
3422/*
3423 * This function is called when the library is unloaded
3424 */
3425void
3426vcom_destructor (void)
3427{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003428 swrap_destructor ();
Dave Wallace048b1d62018-01-03 22:24:41 -05003429 if (vcom->init)
3430 {
3431 vppcom_app_destroy ();
3432 vcom->init = 0;
3433 }
3434
3435 /* Don't use clib_warning() here because that calls writev()
3436 * which will call vcom_init().
3437 */
3438 printf ("%s:%d: LDP<%d>: VCOM destructor: done!\n",
3439 __func__, __LINE__, getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003440}
3441
3442
3443/*
3444 * fd.io coding-style-patch-verification: ON
3445 *
3446 * Local Variables:
3447 * eval: (c-set-style "gnu")
3448 * End:
3449 */