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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <sys/resource.h>
23 #include <netinet/tcp.h>
25 #include <vcl/ldp_socket_wrapper.h>
29 #include <vcl/vppcom.h>
30 #include <vppinfra/time.h>
31 #include <vppinfra/bitmap.h>
32 #include <vppinfra/lock.h>
33 #include <vppinfra/pool.h>
34 #include <vppinfra/hash.h>
36 #define HAVE_CONSTRUCTOR_ATTRIBUTE
37 #ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
38 #define CONSTRUCTOR_ATTRIBUTE \
39 __attribute__ ((constructor))
41 #define CONSTRUCTOR_ATTRIBUTE
42 #endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */
44 #define HAVE_DESTRUCTOR_ATTRIBUTE
45 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE
46 #define DESTRUCTOR_ATTRIBUTE \
47 __attribute__ ((destructor))
49 #define DESTRUCTOR_ATTRIBUTE
52 #define LDP_MAX_NWORKERS 32
54 typedef struct ldp_fd_entry_
61 typedef struct ldp_worker_ctx_
64 clib_time_t clib_time;
69 clib_bitmap_t *rd_bitmap;
70 clib_bitmap_t *wr_bitmap;
71 clib_bitmap_t *ex_bitmap;
72 clib_bitmap_t *sid_rd_bitmap;
73 clib_bitmap_t *sid_wr_bitmap;
74 clib_bitmap_t *sid_ex_bitmap;
75 clib_bitmap_t *libc_rd_bitmap;
76 clib_bitmap_t *libc_wr_bitmap;
77 clib_bitmap_t *libc_ex_bitmap;
84 struct pollfd *libc_poll;
97 ldp_worker_ctx_t *workers;
99 char app_name[LDP_APP_NAME_MAX];
103 ldp_fd_entry_t *fd_pool;
104 clib_rwlock_t fd_table_lock;
105 uword *session_index_to_fd_table;
107 /** vcl needs next epoll_create to go to libc_epoll */
108 u8 vcl_needs_real_epoll;
111 #define LDP_DEBUG ldp->debug
113 #define LDBG(_lvl, _fmt, _args...) \
114 if (ldp->debug > _lvl) \
115 clib_warning (_fmt, ##_args)
117 static ldp_main_t ldp_main = {
118 .sid_bit_val = (1 << LDP_SID_BIT_MIN),
119 .sid_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
120 .debug = LDP_DEBUG_INIT,
123 static ldp_main_t *ldp = &ldp_main;
125 static inline ldp_worker_ctx_t *
126 ldp_worker_get_current (void)
128 return (ldp->workers + vppcom_worker_index ());
132 * RETURN: 0 on success or -1 on error.
135 ldp_set_app_name (char *app_name)
137 int rv = snprintf (ldp->app_name, LDP_APP_NAME_MAX,
138 "ldp-%d-%s", getpid (), app_name);
140 if (rv >= LDP_APP_NAME_MAX)
141 app_name[LDP_APP_NAME_MAX - 1] = 0;
147 if (ldp->app_name[0] == '\0')
148 ldp_set_app_name ("app");
150 return ldp->app_name;
154 ldp_fd_alloc (u32 sid)
158 clib_rwlock_writer_lock (&ldp->fd_table_lock);
159 if (pool_elts (ldp->fd_pool) >= (1ULL << 32) - ldp->sid_bit_val)
161 clib_rwlock_writer_unlock (&ldp->fd_table_lock);
164 pool_get (ldp->fd_pool, fde);
165 fde->session_index = vppcom_session_index (sid);
166 fde->fd_index = fde - ldp->fd_pool;
167 fde->fd = fde->fd_index + ldp->sid_bit_val;
168 hash_set (ldp->session_index_to_fd_table, fde->session_index, fde->fd);
169 clib_rwlock_writer_unlock (&ldp->fd_table_lock);
173 static ldp_fd_entry_t *
174 ldp_fd_entry_get_w_lock (u32 fd_index)
176 clib_rwlock_reader_lock (&ldp->fd_table_lock);
177 if (pool_is_free_index (ldp->fd_pool, fd_index))
180 return pool_elt_at_index (ldp->fd_pool, fd_index);
184 ldp_fd_from_sid (u32 sid)
189 clib_rwlock_reader_lock (&ldp->fd_table_lock);
190 fdp = hash_get (ldp->session_index_to_fd_table, vppcom_session_index (sid));
191 fd = fdp ? *fdp : -EMFILE;
192 clib_rwlock_reader_unlock (&ldp->fd_table_lock);
198 ldp_fd_is_sid (int fd)
200 return fd >= ldp->sid_bit_val;
204 ldp_sid_from_fd (int fd)
206 u32 fd_index, session_index;
209 if (!ldp_fd_is_sid (fd))
210 return INVALID_SESSION_ID;
212 fd_index = fd - ldp->sid_bit_val;
213 fde = ldp_fd_entry_get_w_lock (fd_index);
216 LDBG (0, "unknown fd %d", fd);
217 clib_rwlock_reader_unlock (&ldp->fd_table_lock);
218 return INVALID_SESSION_ID;
220 session_index = fde->session_index;
221 clib_rwlock_reader_unlock (&ldp->fd_table_lock);
223 return vppcom_session_handle (session_index);
227 ldp_fd_free_w_sid (u32 sid)
233 fd = ldp_fd_from_sid (sid);
237 fd_index = fd - ldp->sid_bit_val;
238 fde = ldp_fd_entry_get_w_lock (fd_index);
241 hash_unset (ldp->session_index_to_fd_table, fde->session_index);
242 pool_put (ldp->fd_pool, fde);
244 clib_rwlock_writer_unlock (&ldp->fd_table_lock);
250 ldp_worker_ctx_t *ldpw;
253 if (PREDICT_TRUE (ldp->init))
257 ldp->vcl_needs_real_epoll = 1;
258 rv = vppcom_app_create (ldp_get_app_name ());
261 ldp->vcl_needs_real_epoll = 0;
262 if (rv == VPPCOM_EEXIST)
264 LDBG (2, "\nLDP<%d>: ERROR: ldp_init: vppcom_app_create()"
265 " failed! rv = %d (%s)\n",
266 getpid (), rv, vppcom_retval_str (rv));
270 ldp->vcl_needs_real_epoll = 0;
271 pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
272 ldpw = ldp_worker_get_current ();
274 char *env_var_str = getenv (LDP_ENV_DEBUG);
278 if (sscanf (env_var_str, "%u", &tmp) != 1)
279 clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level specified in"
280 " the env var " LDP_ENV_DEBUG " (%s)!", getpid (),
285 LDBG (0, "LDP<%d>: configured LDP debug level (%u) from env var "
286 LDP_ENV_DEBUG "!", getpid (), ldp->debug);
290 env_var_str = getenv (LDP_ENV_APP_NAME);
293 ldp_set_app_name (env_var_str);
294 LDBG (0, "LDP<%d>: configured LDP app name (%s) from the env var "
295 LDP_ENV_APP_NAME "!", getpid (), ldp->app_name);
298 env_var_str = getenv (LDP_ENV_SID_BIT);
302 if (sscanf (env_var_str, "%u", &sb) != 1)
304 clib_warning ("LDP<%d>: WARNING: Invalid LDP sid bit specified in"
305 " the env var " LDP_ENV_SID_BIT " (%s)! sid bit "
306 "value %d (0x%x)", getpid (), env_var_str,
307 ldp->sid_bit_val, ldp->sid_bit_val);
309 else if (sb < LDP_SID_BIT_MIN)
311 ldp->sid_bit_val = (1 << LDP_SID_BIT_MIN);
312 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
314 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
315 " env var " LDP_ENV_SID_BIT " (%s) is too small. "
316 "Using LDP_SID_BIT_MIN (%d)! sid bit value %d (0x%x)",
317 getpid (), sb, env_var_str, LDP_SID_BIT_MIN,
318 ldp->sid_bit_val, ldp->sid_bit_val);
320 else if (sb > LDP_SID_BIT_MAX)
322 ldp->sid_bit_val = (1 << LDP_SID_BIT_MAX);
323 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
325 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
326 " env var " LDP_ENV_SID_BIT " (%s) is too big. Using"
327 " LDP_SID_BIT_MAX (%d)! sid bit value %d (0x%x)",
328 getpid (), sb, env_var_str, LDP_SID_BIT_MAX,
329 ldp->sid_bit_val, ldp->sid_bit_val);
333 ldp->sid_bit_val = (1 << sb);
334 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
336 LDBG (0, "LDP<%d>: configured LDP sid bit (%u) from "
337 LDP_ENV_SID_BIT "! sid bit value %d (0x%x)", getpid (), sb,
338 ldp->sid_bit_val, ldp->sid_bit_val);
342 clib_time_init (&ldpw->clib_time);
343 clib_rwlock_init (&ldp->fd_table_lock);
344 LDBG (0, "LDP<%d>: LDP initialization: done!", getpid ());
353 const char *func_str;
354 u32 sid = ldp_sid_from_fd (fd);
356 if ((errno = -ldp_init ()))
359 if (sid != INVALID_SESSION_ID)
363 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
364 epfd = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
367 func_str = "libc_close";
369 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): epfd %u (0x%x)",
370 getpid (), fd, fd, func_str, epfd, epfd);
372 rv = libc_close (epfd);
375 u32 size = sizeof (epfd);
378 (void) vppcom_session_attr (sid, VPPCOM_ATTR_SET_LIBC_EPFD,
382 else if (PREDICT_FALSE (epfd < 0))
389 func_str = "vppcom_session_close";
391 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
392 getpid (), fd, fd, func_str, sid, sid);
394 refcnt = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REFCNT, 0, 0);
395 rv = vppcom_session_close (sid);
402 ldp_fd_free_w_sid (sid);
406 func_str = "libc_close";
408 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s()", getpid (), fd, fd,
411 rv = libc_close (fd);
419 int errno_val = errno;
421 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
422 "rv %d, errno = %d", getpid (), fd, fd,
423 func_str, rv, errno_val);
427 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
428 getpid (), fd, fd, rv, rv);
434 read (int fd, void *buf, size_t nbytes)
437 const char *func_str;
438 u32 sid = ldp_sid_from_fd (fd);
440 if ((errno = -ldp_init ()))
443 if (sid != INVALID_SESSION_ID)
445 func_str = "vppcom_session_read";
448 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
449 "sid %u (0x%x), buf %p, nbytes %u", getpid (),
450 fd, fd, func_str, sid, sid, buf, nbytes);
452 size = vppcom_session_read (sid, buf, nbytes);
461 func_str = "libc_read";
464 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
465 "buf %p, nbytes %u", getpid (),
466 fd, fd, func_str, buf, nbytes);
468 size = libc_read (fd, buf, nbytes);
475 int errno_val = errno;
477 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
478 "rv %d, errno = %d", getpid (), fd, fd,
479 func_str, size, errno_val);
483 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
484 getpid (), fd, fd, size, size);
490 readv (int fd, const struct iovec * iov, int iovcnt)
492 const char *func_str;
494 u32 sid = ldp_sid_from_fd (fd);
495 int rv = 0, i, total = 0;
497 if ((errno = -ldp_init ()))
500 if (sid != INVALID_SESSION_ID)
502 func_str = "vppcom_session_read";
505 for (i = 0; i < iovcnt; ++i)
508 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s() [%d]: "
509 "sid %u (0x%x), iov %p, iovcnt %d, total %d",
510 getpid (), fd, fd, func_str, i, sid, sid,
513 rv = vppcom_session_read (sid, iov[i].iov_base, iov[i].iov_len);
519 if (rv < iov[i].iov_len)
522 clib_warning ("LDP<%d>: fd %d (0x%x): "
523 "rv (%d) < iov[%d].iov_len (%d)",
524 getpid (), fd, fd, rv, i,
531 while ((rv >= 0) && (total == 0));
543 func_str = "libc_readv";
546 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
547 "iov %p, iovcnt %d", getpid (), fd, fd, iov, iovcnt);
549 size = libc_readv (fd, iov, iovcnt);
556 int errno_val = errno;
558 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
559 "rv %d, errno = %d", getpid (), fd, fd,
560 func_str, size, errno_val);
564 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
565 getpid (), fd, fd, size, size);
571 write (int fd, const void *buf, size_t nbytes)
573 const char *func_str;
575 u32 sid = ldp_sid_from_fd (fd);
577 if ((errno = -ldp_init ()))
580 if (sid != INVALID_SESSION_ID)
582 func_str = "vppcom_session_write";
585 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
586 "sid %u (0x%x), buf %p, nbytes %u", getpid (),
587 fd, fd, func_str, sid, sid, buf, nbytes);
589 size = vppcom_session_write (sid, (void *) buf, nbytes);
598 func_str = "libc_write";
601 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
602 "buf %p, nbytes %u", getpid (),
603 fd, fd, func_str, buf, nbytes);
605 size = libc_write (fd, buf, nbytes);
612 int errno_val = errno;
614 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
615 "rv %d, errno = %d", getpid (), fd, fd,
616 func_str, size, errno_val);
620 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
621 getpid (), fd, fd, size, size);
627 writev (int fd, const struct iovec * iov, int iovcnt)
629 const char *func_str;
630 ssize_t size = 0, total = 0;
631 u32 sid = ldp_sid_from_fd (fd);
635 * Use [f]printf() instead of clib_warning() to prevent recursion SIGSEGV.
638 if ((errno = -ldp_init ()))
641 if (sid != INVALID_SESSION_ID)
643 func_str = "vppcom_session_write";
646 for (i = 0; i < iovcnt; ++i)
649 printf ("%s:%d: LDP<%d>: fd %d (0x%x): calling %s() [%d]: "
650 "sid %u (0x%x), buf %p, nbytes %ld, total %ld",
651 __func__, __LINE__, getpid (), fd, fd, func_str,
652 i, sid, sid, iov[i].iov_base, iov[i].iov_len, total);
654 rv = vppcom_session_write (sid, iov[i].iov_base,
661 if (rv < iov[i].iov_len)
664 printf ("%s:%d: LDP<%d>: fd %d (0x%x): "
665 "rv (%d) < iov[%d].iov_len (%ld)",
666 __func__, __LINE__, getpid (), fd, fd,
667 rv, i, iov[i].iov_len);
673 while ((rv >= 0) && (total == 0));
685 func_str = "libc_writev";
688 printf ("%s:%d: LDP<%d>: fd %d (0x%x): calling %s(): "
689 "iov %p, iovcnt %d\n", __func__, __LINE__, getpid (),
690 fd, fd, func_str, iov, iovcnt);
692 size = libc_writev (fd, iov, iovcnt);
699 int errno_val = errno;
702 "%s:%d: LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
703 "rv %ld, errno = %d\n", __func__, __LINE__, getpid (), fd,
704 fd, func_str, size, errno_val);
708 printf ("%s:%d: LDP<%d>: fd %d (0x%x): returning %ld\n",
709 __func__, __LINE__, getpid (), fd, fd, size);
715 fcntl (int fd, int cmd, ...)
717 const char *func_str = __func__;
720 u32 sid = ldp_sid_from_fd (fd);
722 if ((errno = -ldp_init ()))
726 if (sid != INVALID_SESSION_ID)
728 int flags = va_arg (ap, int);
731 size = sizeof (flags);
736 func_str = "vppcom_session_attr[SET_FLAGS]";
737 LDBG (2, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x) "
738 "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid,
739 sid, flags, flags, size);
741 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
746 func_str = "vppcom_session_attr[GET_FLAGS]";
747 LDBG (2, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
748 "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid,
749 sid, flags, flags, size);
751 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
755 LDBG (2, "LDP<%d>: fd %d (0x%x), cmd %d (F_GETFL): %s() "
756 "returned flags %d (0x%x)", getpid (), fd, fd, cmd,
757 func_str, flags, flags);
762 /* TODO handle this */
763 LDBG (0, "F_SETFD ignored flags %u", flags);
778 func_str = "libc_vfcntl";
781 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
782 getpid (), fd, fd, func_str, cmd);
784 rv = libc_vfcntl (fd, cmd, ap);
793 int errno_val = errno;
795 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
796 "rv %d, errno = %d", getpid (), fd, fd,
797 func_str, rv, errno_val);
801 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
802 getpid (), fd, fd, rv, rv);
808 ioctl (int fd, unsigned long int cmd, ...)
810 const char *func_str;
813 u32 sid = ldp_sid_from_fd (fd);
815 if ((errno = -ldp_init ()))
819 if (sid != INVALID_SESSION_ID)
821 func_str = "vppcom_session_attr[GET_NREAD]";
828 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
829 getpid (), fd, fd, func_str, sid, sid);
831 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NREAD, 0, 0);
836 u32 flags = va_arg (ap, int) ? O_NONBLOCK : 0;
837 u32 size = sizeof (flags);
839 /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than
840 * non-blocking, the flags should be read here and merged
844 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
845 "sid %u (0x%x), flags %d (0x%x), size %d",
846 getpid (), fd, fd, func_str, sid, sid,
849 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
866 func_str = "libc_vioctl";
869 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
870 getpid (), fd, fd, func_str, cmd);
872 rv = libc_vioctl (fd, cmd, ap);
879 int errno_val = errno;
881 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
882 "rv %d, errno = %d", getpid (), fd, fd,
883 func_str, rv, errno_val);
887 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
888 getpid (), fd, fd, rv, rv);
895 ldp_pselect (int nfds, fd_set * __restrict readfds,
896 fd_set * __restrict writefds,
897 fd_set * __restrict exceptfds,
898 const struct timespec *__restrict timeout,
899 const __sigset_t * __restrict sigmask)
901 uword sid_bits, sid_bits_set, libc_bits, libc_bits_set;
902 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
903 u32 minbits = clib_max (nfds, BITS (uword)), sid;
904 char *func_str = "##";
916 time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
917 (f64) 0 : (f64) timeout->tv_sec +
918 (f64) timeout->tv_nsec / (f64) 1000000000;
920 /* select as fine grained sleep */
923 LDBG (3, "LDP<%d>: sleeping for %.02f seconds", getpid (),
926 time_out += clib_time_now (&ldpw->clib_time);
927 while (clib_time_now (&ldpw->clib_time) < time_out)
941 if (nfds <= ldp->sid_bit_val)
943 func_str = "libc_pselect";
945 LDBG (3, "LDP<%d>: calling %s(): nfds %d, readfds %p, writefds %p, "
946 "exceptfds %p, timeout %p, sigmask %p", getpid (), func_str, nfds,
947 readfds, writefds, exceptfds, timeout, sigmask);
949 rv = libc_pselect (nfds, readfds, writefds, exceptfds,
954 if (PREDICT_FALSE (ldp->sid_bit_val > FD_SETSIZE / 2))
956 clib_warning ("LDP<%d>: ERROR: LDP sid bit value %d (0x%x) > "
957 "FD_SETSIZE/2 %d (0x%x)!", getpid (),
958 ldp->sid_bit_val, ldp->sid_bit_val,
959 FD_SETSIZE / 2, FD_SETSIZE / 2);
964 sid_bits = libc_bits = 0;
965 u32 n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0);
968 clib_bitmap_validate (ldpw->sid_rd_bitmap, minbits);
969 clib_bitmap_validate (ldpw->libc_rd_bitmap, minbits);
970 clib_bitmap_validate (ldpw->rd_bitmap, minbits);
971 clib_memcpy_fast (ldpw->rd_bitmap, readfds, n_bytes);
972 memset (readfds, 0, n_bytes);
975 clib_bitmap_foreach (fd, ldpw->rd_bitmap, ({
978 sid = ldp_sid_from_fd (fd);
979 LDBG (3, "LDP<%d>: readfds: fd %d (0x%x), sid %u (0x%x)",
980 getpid (), fd, fd, sid, sid);
981 if (sid == INVALID_SESSION_ID)
982 clib_bitmap_set_no_check (ldpw->libc_rd_bitmap, fd, 1);
984 clib_bitmap_set_no_check (ldpw->sid_rd_bitmap,
985 vppcom_session_index (sid), 1);
989 sid_bits_set = clib_bitmap_last_set (ldpw->sid_rd_bitmap) + 1;
990 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
992 libc_bits_set = clib_bitmap_last_set (ldpw->libc_rd_bitmap) + 1;
993 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
995 LDBG (3, "LDP<%d>: readfds: sid_bits_set %d, sid_bits %d, "
996 "libc_bits_set %d, libc_bits %d", getpid (), sid_bits_set,
997 sid_bits, libc_bits_set, libc_bits);
1001 clib_bitmap_validate (ldpw->sid_wr_bitmap, minbits);
1002 clib_bitmap_validate (ldpw->libc_wr_bitmap, minbits);
1003 clib_bitmap_validate (ldpw->wr_bitmap, minbits);
1004 clib_memcpy_fast (ldpw->wr_bitmap, writefds, n_bytes);
1005 memset (writefds, 0, n_bytes);
1008 clib_bitmap_foreach (fd, ldpw->wr_bitmap, ({
1011 sid = ldp_sid_from_fd (fd);
1012 LDBG (3, "LDP<%d>: writefds: fd %d (0x%x), sid %u (0x%x)",
1013 getpid (), fd, fd, sid, sid);
1014 if (sid == INVALID_SESSION_ID)
1015 clib_bitmap_set_no_check (ldpw->libc_wr_bitmap, fd, 1);
1017 clib_bitmap_set_no_check (ldpw->sid_wr_bitmap,
1018 vppcom_session_index (sid), 1);
1022 sid_bits_set = clib_bitmap_last_set (ldpw->sid_wr_bitmap) + 1;
1023 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
1025 libc_bits_set = clib_bitmap_last_set (ldpw->libc_wr_bitmap) + 1;
1026 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
1028 LDBG (3, "LDP<%d>: writefds: sid_bits_set %d, sid_bits %d, "
1029 "libc_bits_set %d, libc_bits %d", getpid (),
1030 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
1034 clib_bitmap_validate (ldpw->sid_ex_bitmap, minbits);
1035 clib_bitmap_validate (ldpw->libc_ex_bitmap, minbits);
1036 clib_bitmap_validate (ldpw->ex_bitmap, minbits);
1037 clib_memcpy_fast (ldpw->ex_bitmap, exceptfds, n_bytes);
1038 memset (exceptfds, 0, n_bytes);
1041 clib_bitmap_foreach (fd, ldpw->ex_bitmap, ({
1044 sid = ldp_sid_from_fd (fd);
1045 LDBG (3, "LDP<%d>: exceptfds: fd %d (0x%x), sid %u (0x%x)",
1046 getpid (), fd, fd, sid, sid);
1047 if (sid == INVALID_SESSION_ID)
1048 clib_bitmap_set_no_check (ldpw->libc_ex_bitmap, fd, 1);
1050 clib_bitmap_set_no_check (ldpw->sid_ex_bitmap,
1051 vppcom_session_index (sid), 1);
1055 sid_bits_set = clib_bitmap_last_set (ldpw->sid_ex_bitmap) + 1;
1056 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
1058 libc_bits_set = clib_bitmap_last_set (ldpw->libc_ex_bitmap) + 1;
1059 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
1061 LDBG (3, "LDP<%d>: exceptfds: sid_bits_set %d, sid_bits %d, "
1062 "libc_bits_set %d, libc_bits %d", getpid (),
1063 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
1066 if (PREDICT_FALSE (!sid_bits && !libc_bits))
1077 if (!ldpw->select_vcl)
1079 func_str = "vppcom_select";
1082 clib_memcpy_fast (ldpw->rd_bitmap, ldpw->sid_rd_bitmap,
1083 vec_len (ldpw->rd_bitmap) *
1084 sizeof (clib_bitmap_t));
1086 clib_memcpy_fast (ldpw->wr_bitmap, ldpw->sid_wr_bitmap,
1087 vec_len (ldpw->wr_bitmap) *
1088 sizeof (clib_bitmap_t));
1090 clib_memcpy_fast (ldpw->ex_bitmap, ldpw->sid_ex_bitmap,
1091 vec_len (ldpw->ex_bitmap) *
1092 sizeof (clib_bitmap_t));
1094 rv = vppcom_select (sid_bits,
1095 readfds ? ldpw->rd_bitmap : NULL,
1096 writefds ? ldpw->wr_bitmap : NULL,
1097 exceptfds ? ldpw->ex_bitmap : NULL, 0);
1108 clib_bitmap_foreach (sid, ldpw->rd_bitmap,
1110 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
1111 if (PREDICT_FALSE (fd < 0))
1117 FD_SET (fd, readfds);
1124 clib_bitmap_foreach (sid, ldpw->wr_bitmap,
1126 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
1127 if (PREDICT_FALSE (fd < 0))
1133 FD_SET (fd, writefds);
1140 clib_bitmap_foreach (sid, ldpw->ex_bitmap,
1142 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
1143 if (PREDICT_FALSE (fd < 0))
1149 FD_SET (fd, exceptfds);
1153 ldpw->select_vcl = 1;
1158 ldpw->select_vcl = 0;
1162 struct timespec tspec;
1164 func_str = "libc_pselect";
1167 clib_memcpy_fast (readfds, ldpw->libc_rd_bitmap,
1168 vec_len (ldpw->rd_bitmap) *
1169 sizeof (clib_bitmap_t));
1171 clib_memcpy_fast (writefds, ldpw->libc_wr_bitmap,
1172 vec_len (ldpw->wr_bitmap) *
1173 sizeof (clib_bitmap_t));
1175 clib_memcpy_fast (exceptfds, ldpw->libc_ex_bitmap,
1176 vec_len (ldpw->ex_bitmap) *
1177 sizeof (clib_bitmap_t));
1178 tspec.tv_sec = tspec.tv_nsec = 0;
1179 rv = libc_pselect (libc_bits,
1180 readfds ? readfds : NULL,
1181 writefds ? writefds : NULL,
1182 exceptfds ? exceptfds : NULL, &tspec, sigmask);
1187 while ((time_out == -1) || (clib_time_now (&ldpw->clib_time) < time_out));
1191 /* TBD: set timeout to amount of time left */
1192 clib_bitmap_zero (ldpw->rd_bitmap);
1193 clib_bitmap_zero (ldpw->sid_rd_bitmap);
1194 clib_bitmap_zero (ldpw->libc_rd_bitmap);
1195 clib_bitmap_zero (ldpw->wr_bitmap);
1196 clib_bitmap_zero (ldpw->sid_wr_bitmap);
1197 clib_bitmap_zero (ldpw->libc_wr_bitmap);
1198 clib_bitmap_zero (ldpw->ex_bitmap);
1199 clib_bitmap_zero (ldpw->sid_ex_bitmap);
1200 clib_bitmap_zero (ldpw->libc_ex_bitmap);
1206 int errno_val = errno;
1208 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1209 "rv %d, errno = %d", getpid (),
1210 func_str, rv, errno_val);
1214 clib_warning ("LDP<%d>: returning %d (0x%x)", getpid (), rv, rv);
1220 select (int nfds, fd_set * __restrict readfds,
1221 fd_set * __restrict writefds,
1222 fd_set * __restrict exceptfds, struct timeval *__restrict timeout)
1224 struct timespec tspec;
1228 tspec.tv_sec = timeout->tv_sec;
1229 tspec.tv_nsec = timeout->tv_usec * 1000;
1231 return ldp_pselect (nfds, readfds, writefds, exceptfds,
1232 timeout ? &tspec : NULL, NULL);
1235 #ifdef __USE_XOPEN2K
1237 pselect (int nfds, fd_set * __restrict readfds,
1238 fd_set * __restrict writefds,
1239 fd_set * __restrict exceptfds,
1240 const struct timespec *__restrict timeout,
1241 const __sigset_t * __restrict sigmask)
1243 return ldp_pselect (nfds, readfds, writefds, exceptfds, timeout, 0);
1248 socket (int domain, int type, int protocol)
1250 const char *func_str;
1252 u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
1253 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1255 if ((errno = -ldp_init ()))
1258 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1259 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
1262 u8 proto = ((sock_type == SOCK_DGRAM) ?
1263 VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
1265 func_str = "vppcom_session_create";
1267 LDBG (0, "LDP<%d>: : calling %s(): proto %u (%s), is_nonblocking %u",
1268 getpid (), func_str, proto, vppcom_proto_str (proto),
1271 sid = vppcom_session_create (proto, is_nonblocking);
1279 func_str = "ldp_fd_from_sid";
1280 rv = ldp_fd_alloc (sid);
1283 (void) vppcom_session_close (sid);
1291 func_str = "libc_socket";
1293 LDBG (0, "LDP<%d>: : calling %s()", getpid (), func_str);
1295 rv = libc_socket (domain, type, protocol);
1302 int errno_val = errno;
1304 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1305 "rv %d, errno = %d",
1306 getpid (), func_str, rv, errno_val);
1310 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1316 * Create two new sockets, of type TYPE in domain DOMAIN and using
1317 * protocol PROTOCOL, which are connected to each other, and put file
1318 * descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
1319 * one will be chosen automatically.
1320 * Returns 0 on success, -1 for errors.
1323 socketpair (int domain, int type, int protocol, int fds[2])
1325 const char *func_str;
1327 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1329 if ((errno = -ldp_init ()))
1332 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1333 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
1335 func_str = __func__;
1337 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1343 func_str = "libc_socket";
1345 LDBG (1, "LDP<%d>: : calling %s()", getpid (), func_str);
1347 rv = libc_socketpair (domain, type, protocol, fds);
1354 int errno_val = errno;
1356 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1357 "rv %d, errno = %d",
1358 getpid (), func_str, rv, errno_val);
1362 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1368 bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
1371 const char *func_str;
1372 u32 sid = ldp_sid_from_fd (fd);
1374 if ((errno = -ldp_init ()))
1377 if (sid != INVALID_SESSION_ID)
1381 func_str = "vppcom_session_bind";
1383 switch (addr->sa_family)
1386 if (len != sizeof (struct sockaddr_in))
1389 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1390 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1395 ep.is_ip4 = VPPCOM_IS_IP4;
1396 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1397 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1401 if (len != sizeof (struct sockaddr_in6))
1404 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1405 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1410 ep.is_ip4 = VPPCOM_IS_IP6;
1411 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1412 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
1416 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): "
1417 "Unsupported address family %u!",
1418 getpid (), fd, fd, sid, sid, addr->sa_family);
1419 errno = EAFNOSUPPORT;
1424 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1426 getpid (), fd, fd, func_str, sid, sid, addr, len);
1428 rv = vppcom_session_bind (sid, &ep);
1429 if (rv != VPPCOM_OK)
1437 func_str = "libc_bind";
1440 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1442 getpid (), fd, fd, func_str, addr, len);
1444 rv = libc_bind (fd, addr, len);
1452 int errno_val = errno;
1454 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1455 "rv %d, errno = %d", getpid (), fd, fd,
1456 func_str, rv, errno_val);
1460 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1461 getpid (), fd, fd, rv, rv);
1467 ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
1468 vppcom_endpt_t * ep)
1471 int sa_len, copy_len;
1473 if ((errno = -ldp_init ()))
1476 if (addr && len && ep)
1478 addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6;
1479 switch (addr->sa_family)
1482 ((struct sockaddr_in *) addr)->sin_port = ep->port;
1483 if (*len > sizeof (struct sockaddr_in))
1484 *len = sizeof (struct sockaddr_in);
1485 sa_len = sizeof (struct sockaddr_in) - sizeof (struct in_addr);
1486 copy_len = *len - sa_len;
1488 memcpy (&((struct sockaddr_in *) addr)->sin_addr, ep->ip,
1493 ((struct sockaddr_in6 *) addr)->sin6_port = ep->port;
1494 if (*len > sizeof (struct sockaddr_in6))
1495 *len = sizeof (struct sockaddr_in6);
1496 sa_len = sizeof (struct sockaddr_in6) - sizeof (struct in6_addr);
1497 copy_len = *len - sa_len;
1499 memcpy (((struct sockaddr_in6 *) addr)->sin6_addr.
1500 __in6_u.__u6_addr8, ep->ip, copy_len);
1513 getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
1516 const char *func_str;
1517 u32 sid = ldp_sid_from_fd (fd);
1519 if ((errno = -ldp_init ()))
1522 if (sid != INVALID_SESSION_ID)
1525 u8 addr_buf[sizeof (struct in6_addr)];
1526 u32 size = sizeof (ep);
1529 func_str = "vppcom_session_attr[GET_LCL_ADDR]";
1532 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1534 getpid (), fd, fd, func_str, sid, sid, addr, len);
1536 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
1537 if (rv != VPPCOM_OK)
1544 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
1545 if (rv != VPPCOM_OK)
1554 func_str = "libc_getsockname";
1557 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1559 getpid (), fd, fd, func_str, addr, len);
1561 rv = libc_getsockname (fd, addr, len);
1568 int errno_val = errno;
1570 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1571 "rv %d, errno = %d", getpid (), fd, fd,
1572 func_str, rv, errno_val);
1576 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1577 getpid (), fd, fd, rv, rv);
1583 connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
1586 const char *func_str = __func__;
1587 u32 sid = ldp_sid_from_fd (fd);
1589 if ((errno = -ldp_init ()))
1594 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): NULL addr, len %u",
1595 getpid (), fd, fd, len);
1601 if (sid != INVALID_SESSION_ID)
1605 func_str = "vppcom_session_connect";
1607 switch (addr->sa_family)
1610 if (len != sizeof (struct sockaddr_in))
1613 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1614 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1619 ep.is_ip4 = VPPCOM_IS_IP4;
1620 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1621 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1625 if (len != sizeof (struct sockaddr_in6))
1628 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1629 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1634 ep.is_ip4 = VPPCOM_IS_IP6;
1635 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1636 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
1640 clib_warning ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): "
1641 "Unsupported address family %u!",
1642 getpid (), fd, fd, sid, sid, addr->sa_family);
1643 errno = EAFNOSUPPORT;
1648 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x) "
1650 getpid (), fd, fd, func_str, sid, sid, addr, len);
1652 rv = vppcom_session_connect (sid, &ep);
1653 if (rv != VPPCOM_OK)
1661 func_str = "libc_connect";
1664 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1666 getpid (), fd, fd, func_str, addr, len);
1668 rv = libc_connect (fd, addr, len);
1676 int errno_val = errno;
1678 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1679 "rv %d, errno = %d", getpid (), fd, fd,
1680 func_str, rv, errno_val);
1684 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1685 getpid (), fd, fd, rv, rv);
1691 getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
1694 const char *func_str;
1695 u32 sid = ldp_sid_from_fd (fd);
1697 if ((errno = -ldp_init ()))
1700 if (sid != INVALID_SESSION_ID)
1703 u8 addr_buf[sizeof (struct in6_addr)];
1704 u32 size = sizeof (ep);
1707 func_str = "vppcom_session_attr[GET_PEER_ADDR]";
1710 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1712 getpid (), fd, fd, func_str, sid, sid, addr, len);
1714 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
1715 if (rv != VPPCOM_OK)
1722 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
1723 if (rv != VPPCOM_OK)
1732 func_str = "libc_getpeername";
1735 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1737 getpid (), fd, fd, func_str, addr, len);
1739 rv = libc_getpeername (fd, addr, len);
1746 int errno_val = errno;
1748 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1749 "rv %d, errno = %d", getpid (), fd, fd,
1750 func_str, rv, errno_val);
1754 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1755 getpid (), fd, fd, rv, rv);
1761 send (int fd, const void *buf, size_t n, int flags)
1764 const char *func_str;
1765 u32 sid = ldp_sid_from_fd (fd);
1767 if ((errno = -ldp_init ()))
1770 if (sid != INVALID_SESSION_ID)
1773 func_str = "vppcom_session_sendto";
1776 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1777 "buf %p, n %u, flags 0x%x",
1778 getpid (), fd, fd, func_str, sid, sid, buf, n, flags);
1780 size = vppcom_session_sendto (sid, (void *) buf, n, flags, NULL);
1781 if (size < VPPCOM_OK)
1789 func_str = "libc_send";
1792 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1793 "buf %p, n %u, flags 0x%x",
1794 getpid (), fd, fd, func_str, buf, n, flags);
1796 size = libc_send (fd, buf, n, flags);
1803 int errno_val = errno;
1805 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1806 "rv %d, errno = %d", getpid (), fd, fd,
1807 func_str, size, errno_val);
1811 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1812 getpid (), fd, fd, size, size);
1818 sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
1820 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
1822 const char *func_str;
1823 u32 sid = ldp_sid_from_fd (out_fd);
1825 if ((errno = -ldp_init ()))
1828 if (sid != INVALID_SESSION_ID)
1831 ssize_t results = 0;
1832 size_t n_bytes_left = len;
1833 size_t bytes_to_read;
1837 u32 flags, flags_len = sizeof (flags);
1839 func_str = "vppcom_session_attr[GET_FLAGS]";
1840 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
1842 if (PREDICT_FALSE (rv != VPPCOM_OK))
1844 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1845 "sid %u (0x%x), returned %d (%s)!", getpid (),
1846 out_fd, out_fd, func_str, sid, sid, rv,
1847 vppcom_retval_str (rv));
1849 vec_reset_length (ldpw->io_buffer);
1857 off_t off = lseek (in_fd, *offset, SEEK_SET);
1858 if (PREDICT_FALSE (off == -1))
1862 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1863 "SEEK_SET failed: in_fd %d, offset %p, "
1864 "*offset %ld, rv %ld, errno %d", getpid (),
1865 out_fd, out_fd, in_fd, offset, *offset, off,
1872 ASSERT (off == *offset);
1877 func_str = "vppcom_session_attr[GET_NWRITE]";
1878 size = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NWRITE, 0, 0);
1882 ("LDP<%d>: ERROR: fd %d (0x%x): %s(): sid %u (0x%x), "
1883 "returned %d (%s)!", getpid (), out_fd, out_fd, func_str,
1884 sid, sid, size, vppcom_retval_str (size));
1885 vec_reset_length (ldpw->io_buffer);
1891 bytes_to_read = size;
1894 ("LDP<%d>: fd %d (0x%x): called %s(): sid %u (0x%x), "
1895 "results %ld, n_bytes_left %lu, bytes_to_read %lu", getpid (),
1896 out_fd, out_fd, func_str, sid, sid, results, n_bytes_left,
1899 if (bytes_to_read == 0)
1901 if (flags & O_NONBLOCK)
1906 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1908 getpid (), out_fd, out_fd, sid, sid);
1916 bytes_to_read = clib_min (n_bytes_left, bytes_to_read);
1917 vec_validate (ldpw->io_buffer, bytes_to_read);
1918 nbytes = libc_read (in_fd, ldpw->io_buffer, bytes_to_read);
1921 func_str = "libc_read";
1923 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): in_fd (%d), "
1924 "io_buffer %p, bytes_to_read %lu, rv %d, "
1925 "errno %d", getpid (), out_fd, out_fd, func_str,
1926 in_fd, ldpw->io_buffer, bytes_to_read, nbytes,
1932 vec_reset_length (ldpw->io_buffer);
1938 func_str = "vppcom_session_write";
1941 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1942 "buf %p, nbytes %u: results %d, n_bytes_left %d", getpid (),
1943 out_fd, out_fd, func_str, sid, sid, ldpw->io_buffer, nbytes,
1944 results, n_bytes_left);
1946 size = vppcom_session_write (sid, ldpw->io_buffer, nbytes);
1949 if (size == VPPCOM_EAGAIN)
1951 if (flags & O_NONBLOCK)
1957 ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1958 "EAGAIN", getpid (), out_fd, out_fd, sid, sid);
1968 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s():"
1969 "sid %u, io_buffer %p, nbytes %u "
1971 getpid (), out_fd, out_fd, func_str,
1972 sid, ldpw->io_buffer, nbytes,
1973 size, vppcom_retval_str (size));
1977 vec_reset_length (ldpw->io_buffer);
1986 ASSERT (n_bytes_left >= nbytes);
1987 n_bytes_left = n_bytes_left - nbytes;
1989 while (n_bytes_left > 0);
1992 vec_reset_length (ldpw->io_buffer);
1995 off_t off = lseek (in_fd, *offset, SEEK_SET);
1996 if (PREDICT_FALSE (off == -1))
2000 clib_warning ("LDP<%d>: ERROR: %s(): SEEK_SET failed: "
2001 "in_fd %d, offset %p, *offset %ld, "
2002 "rv %ld, errno %d", getpid (), in_fd,
2003 offset, *offset, off, errno_val);
2009 ASSERT (off == *offset);
2010 *offset += results + 1;
2022 func_str = "libc_send";
2025 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2026 "in_fd %d, offset %p, len %u",
2027 getpid (), out_fd, out_fd, func_str,
2028 in_fd, offset, len);
2030 size = libc_sendfile (out_fd, in_fd, offset, len);
2038 int errno_val = errno;
2040 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2041 "rv %d, errno = %d", getpid (), out_fd, out_fd,
2042 func_str, size, errno_val);
2046 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2047 getpid (), out_fd, out_fd, size, size);
2053 sendfile64 (int out_fd, int in_fd, off_t * offset, size_t len)
2055 return sendfile (out_fd, in_fd, offset, len);
2059 recv (int fd, void *buf, size_t n, int flags)
2062 const char *func_str;
2063 u32 sid = ldp_sid_from_fd (fd);
2065 if ((errno = -ldp_init ()))
2068 if (sid != INVALID_SESSION_ID)
2070 func_str = "vppcom_session_recvfrom";
2073 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2074 "sid %u (0x%x), buf %p, n %u, flags 0x%x", getpid (),
2075 fd, fd, func_str, sid, sid, buf, n, flags);
2077 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
2086 func_str = "libc_recv";
2089 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2090 "buf %p, n %u, flags 0x%x", getpid (),
2091 fd, fd, func_str, buf, n, flags);
2093 size = libc_recv (fd, buf, n, flags);
2100 int errno_val = errno;
2102 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2103 "rv %d, errno = %d", getpid (), fd, fd,
2104 func_str, size, errno_val);
2108 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2109 getpid (), fd, fd, size, size);
2115 sendto (int fd, const void *buf, size_t n, int flags,
2116 __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
2119 const char *func_str = __func__;
2120 u32 sid = ldp_sid_from_fd (fd);
2122 if ((errno = -ldp_init ()))
2125 if (sid != INVALID_SESSION_ID)
2127 vppcom_endpt_t *ep = 0;
2133 switch (addr->sa_family)
2136 ep->is_ip4 = VPPCOM_IS_IP4;
2138 (uint8_t *) & ((const struct sockaddr_in *) addr)->sin_addr;
2140 (uint16_t) ((const struct sockaddr_in *) addr)->sin_port;
2144 ep->is_ip4 = VPPCOM_IS_IP6;
2146 (uint8_t *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
2148 (uint16_t) ((const struct sockaddr_in6 *) addr)->sin6_port;
2152 errno = EAFNOSUPPORT;
2158 func_str = "vppcom_session_sendto";
2161 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2162 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2163 getpid (), fd, fd, func_str, sid, sid, buf, n,
2166 size = vppcom_session_sendto (sid, (void *) buf, n, flags, ep);
2175 func_str = "libc_sendto";
2178 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2179 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2180 getpid (), fd, fd, func_str, buf, n, flags,
2183 size = libc_sendto (fd, buf, n, flags, addr, addr_len);
2191 int errno_val = errno;
2193 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2194 "rv %d, errno = %d", getpid (), fd, fd,
2195 func_str, size, errno_val);
2199 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2200 getpid (), fd, fd, size, size);
2206 recvfrom (int fd, void *__restrict buf, size_t n, int flags,
2207 __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
2210 const char *func_str;
2211 u32 sid = ldp_sid_from_fd (fd);
2213 if ((errno = -ldp_init ()))
2216 if (sid != INVALID_SESSION_ID)
2219 u8 src_addr[sizeof (struct sockaddr_in6)];
2221 func_str = "vppcom_session_recvfrom";
2224 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2225 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2226 getpid (), fd, fd, func_str, sid, sid, buf, n,
2231 size = vppcom_session_recvfrom (sid, buf, n, flags, &ep);
2234 size = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
2237 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
2247 func_str = "libc_recvfrom";
2250 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2251 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2252 getpid (), fd, fd, func_str, buf, n, flags,
2255 size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
2262 int errno_val = errno;
2264 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2265 "rv %d, errno = %d", getpid (), fd, fd,
2266 func_str, size, errno_val);
2270 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2271 getpid (), fd, fd, size, size);
2277 sendmsg (int fd, const struct msghdr * message, int flags)
2280 const char *func_str;
2281 u32 sid = ldp_sid_from_fd (fd);
2283 if ((errno = -ldp_init ()))
2286 if (sid != INVALID_SESSION_ID)
2288 func_str = __func__;
2290 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2296 func_str = "libc_sendmsg";
2299 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2300 "message %p, flags 0x%x",
2301 getpid (), fd, fd, func_str, message, flags);
2303 size = libc_sendmsg (fd, message, flags);
2310 int errno_val = errno;
2312 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2313 "rv %d, errno = %d", getpid (), fd, fd,
2314 func_str, size, errno_val);
2318 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2319 getpid (), fd, fd, size, size);
2326 sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
2329 const char *func_str;
2330 u32 sid = ldp_sid_from_fd (fd);
2332 if ((errno = -ldp_init ()))
2335 if (sid != INVALID_SESSION_ID)
2337 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2343 func_str = "libc_sendmmsg";
2346 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2347 "vmessages %p, vlen %u, flags 0x%x",
2348 getpid (), fd, fd, func_str, vmessages, vlen, flags);
2350 size = libc_sendmmsg (fd, vmessages, vlen, flags);
2357 int errno_val = errno;
2359 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2360 "rv %d, errno = %d", getpid (), fd, fd,
2361 func_str, size, errno_val);
2365 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2366 getpid (), fd, fd, size, size);
2373 recvmsg (int fd, struct msghdr * message, int flags)
2376 const char *func_str;
2377 u32 sid = ldp_sid_from_fd (fd);
2379 if ((errno = -ldp_init ()))
2382 if (sid != INVALID_SESSION_ID)
2384 func_str = __func__;
2386 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2392 func_str = "libc_recvmsg";
2395 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2396 "message %p, flags 0x%x",
2397 getpid (), fd, fd, func_str, message, flags);
2399 size = libc_recvmsg (fd, message, flags);
2406 int errno_val = errno;
2408 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2409 "rv %d, errno = %d", getpid (), fd, fd,
2410 func_str, size, errno_val);
2414 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2415 getpid (), fd, fd, size, size);
2422 recvmmsg (int fd, struct mmsghdr *vmessages,
2423 unsigned int vlen, int flags, struct timespec *tmo)
2426 const char *func_str;
2427 u32 sid = ldp_sid_from_fd (fd);
2429 if ((errno = -ldp_init ()))
2432 if (sid != INVALID_SESSION_ID)
2434 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2440 func_str = "libc_recvmmsg";
2443 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2444 "vmessages %p, vlen %u, flags 0x%x, tmo %p",
2445 getpid (), fd, fd, func_str, vmessages, vlen,
2448 size = libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
2455 int errno_val = errno;
2457 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2458 "rv %d, errno = %d", getpid (), fd, fd,
2459 func_str, size, errno_val);
2463 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2464 getpid (), fd, fd, size, size);
2471 getsockopt (int fd, int level, int optname,
2472 void *__restrict optval, socklen_t * __restrict optlen)
2475 const char *func_str = __func__;
2476 u32 sid = ldp_sid_from_fd (fd);
2477 u32 buflen = optlen ? (u32) * optlen : 0;
2479 if ((errno = -ldp_init ()))
2482 if (sid != INVALID_SESSION_ID)
2492 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_NODELAY]";
2494 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2496 getpid (), fd, fd, func_str, sid, sid);
2497 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_NODELAY,
2501 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_USER_MSS]";
2503 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2505 getpid (), fd, fd, func_str, sid, sid);
2506 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_USER_MSS,
2510 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPIDLE]";
2512 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2514 getpid (), fd, fd, func_str, sid, sid);
2515 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
2519 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPINTVL]";
2521 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2522 "sid %u (0x%x), SOL_TCP",
2523 getpid (), fd, fd, func_str, sid, sid);
2524 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
2528 if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
2531 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x), "
2532 "SOL_TCP, TCP_INFO, optval %p, "
2533 "optlen %d: #LDP-NOP#",
2534 getpid (), fd, fd, sid, sid,
2536 memset (optval, 0, *optlen);
2544 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2545 "sid %u (0x%x), SOL_TCP, "
2546 "optname %d unsupported!",
2547 getpid (), fd, fd, func_str, sid, sid, optname);
2555 func_str = "vppcom_session_attr[SOL_IPV6,GET_V6ONLY]";
2557 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2559 getpid (), fd, fd, func_str, sid, sid);
2560 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_V6ONLY,
2565 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2566 "sid %u (0x%x), SOL_IPV6, "
2567 "optname %d unsupported!",
2568 getpid (), fd, fd, func_str, sid, sid, optname);
2576 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ACCEPTCONN]";
2578 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2580 getpid (), fd, fd, func_str, sid, sid);
2581 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LISTEN,
2585 func_str = "vppcom_session_attr[SOL_SOCKET,GET_KEEPALIVE]";
2587 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2589 getpid (), fd, fd, func_str, sid, sid);
2590 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_KEEPALIVE,
2594 func_str = "vppcom_session_attr[SOL_SOCKET,GET_PROTOCOL]";
2596 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2598 getpid (), fd, fd, func_str, sid, sid);
2599 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PROTOCOL,
2601 *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
2604 func_str = "vppcom_session_attr[SOL_SOCKET,GET_TX_FIFO_LEN]";
2606 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2607 "sid %u (0x%x), optlen %d",
2608 getpid (), fd, fd, func_str, sid, sid, buflen);
2609 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TX_FIFO_LEN,
2613 func_str = "vppcom_session_attr[SOL_SOCKET,GET_RX_FIFO_LEN]";
2615 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2616 "sid %u (0x%x), optlen %d",
2617 getpid (), fd, fd, func_str, sid, sid, buflen);
2618 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_RX_FIFO_LEN,
2622 func_str = "vppcom_session_attr[SOL_SOCKET,GET_REUSEADDR]";
2624 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2626 getpid (), fd, fd, func_str, sid, sid);
2627 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REUSEADDR,
2631 func_str = "vppcom_session_attr[SOL_SOCKET,GET_BROADCAST]";
2633 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2635 getpid (), fd, fd, func_str, sid, sid);
2636 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_BROADCAST,
2640 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ERROR]";
2642 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2644 getpid (), fd, fd, func_str, sid, sid);
2645 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_ERROR,
2650 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2651 "sid %u (0x%x), SOL_SOCKET, "
2652 "optname %d unsupported!",
2653 getpid (), fd, fd, func_str, sid, sid, optname);
2661 if (rv != VPPCOM_OK)
2669 func_str = "libc_getsockopt";
2672 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2673 "optname %d, optval %p, optlen %d",
2674 getpid (), fd, fd, func_str, level, optname,
2677 rv = libc_getsockopt (fd, level, optname, optval, optlen);
2684 int errno_val = errno;
2686 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2687 "rv %d, errno = %d", getpid (), fd, fd,
2688 func_str, rv, errno_val);
2692 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2693 getpid (), fd, fd, rv, rv);
2699 setsockopt (int fd, int level, int optname,
2700 const void *optval, socklen_t optlen)
2703 const char *func_str = __func__;
2704 u32 sid = ldp_sid_from_fd (fd);
2706 if ((errno = -ldp_init ()))
2709 if (sid != INVALID_SESSION_ID)
2719 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_NODELAY]";
2721 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2723 getpid (), fd, fd, func_str, sid, sid);
2724 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_NODELAY,
2725 (void *) optval, &optlen);
2728 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_USER_MSS]";
2730 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2732 getpid (), fd, fd, func_str, sid, sid);
2733 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_USER_MSS,
2734 (void *) optval, &optlen);
2737 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPIDLE]";
2739 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2741 getpid (), fd, fd, func_str, sid, sid);
2742 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
2743 (void *) optval, &optlen);
2746 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPINTVL]";
2748 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2749 "sid %u (0x%x), SOL_TCP",
2750 getpid (), fd, fd, func_str, sid, sid);
2751 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
2752 (void *) optval, &optlen);
2756 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2757 "sid %u (0x%x), SOL_TCP, "
2758 "optname %d unsupported!",
2759 getpid (), fd, fd, func_str, sid, sid, optname);
2767 func_str = "vppcom_session_attr[SOL_IPV6,SET_V6ONLY]";
2769 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2771 getpid (), fd, fd, func_str, sid, sid);
2772 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_V6ONLY,
2773 (void *) optval, &optlen);
2777 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2778 "sid %u (0x%x), SOL_IPV6, "
2779 "optname %d unsupported!",
2780 getpid (), fd, fd, func_str, sid, sid, optname);
2788 func_str = "vppcom_session_attr[SOL_SOCKET,SET_KEEPALIVE]";
2790 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2792 getpid (), fd, fd, func_str, sid, sid);
2793 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_KEEPALIVE,
2794 (void *) optval, &optlen);
2797 func_str = "vppcom_session_attr[SOL_SOCKET,SET_REUSEADDR]";
2799 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2801 getpid (), fd, fd, func_str, sid, sid);
2802 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_REUSEADDR,
2803 (void *) optval, &optlen);
2806 func_str = "vppcom_session_attr[SOL_SOCKET,SET_BROADCAST]";
2808 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2810 getpid (), fd, fd, func_str, sid, sid);
2811 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_BROADCAST,
2812 (void *) optval, &optlen);
2816 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2817 "sid %u (0x%x), SOL_SOCKET, "
2818 "optname %d unsupported!",
2819 getpid (), fd, fd, func_str, sid, sid, optname);
2827 if (rv != VPPCOM_OK)
2835 func_str = "libc_setsockopt";
2838 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2839 "optname %d, optval %p, optlen %d",
2840 getpid (), fd, fd, func_str, level, optname,
2843 rv = libc_setsockopt (fd, level, optname, optval, optlen);
2850 int errno_val = errno;
2852 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2853 "rv %d, errno = %d", getpid (), fd, fd,
2854 func_str, rv, errno_val);
2858 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2859 getpid (), fd, fd, rv, rv);
2865 listen (int fd, int n)
2868 const char *func_str;
2869 u32 sid = ldp_sid_from_fd (fd);
2871 if ((errno = -ldp_init ()))
2874 if (sid != INVALID_SESSION_ID)
2876 func_str = "vppcom_session_listen";
2878 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), n %d",
2879 getpid (), fd, fd, func_str, sid, sid, n);
2881 rv = vppcom_session_listen (sid, n);
2882 if (rv != VPPCOM_OK)
2890 func_str = "libc_listen";
2892 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): n %d", getpid (), fd,
2895 rv = libc_listen (fd, n);
2902 int errno_val = errno;
2904 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2905 "rv %d, errno = %d", getpid (), fd, fd,
2906 func_str, rv, errno_val);
2910 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2911 getpid (), fd, fd, rv, rv);
2917 ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
2918 socklen_t * __restrict addr_len, int flags)
2921 const char *func_str;
2922 u32 listen_sid = ldp_sid_from_fd (listen_fd);
2925 if ((errno = -ldp_init ()))
2928 if (listen_sid != INVALID_SESSION_ID)
2931 u8 src_addr[sizeof (struct sockaddr_in6)];
2932 memset (&ep, 0, sizeof (ep));
2935 func_str = "vppcom_session_accept";
2938 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2939 "listen sid %u (0x%x), ep %p, flags 0x%x",
2940 getpid (), listen_fd, listen_fd, func_str,
2941 listen_sid, listen_sid, ep, flags);
2943 accept_sid = vppcom_session_accept (listen_sid, &ep, flags);
2946 errno = -accept_sid;
2951 rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
2952 if (rv != VPPCOM_OK)
2954 (void) vppcom_session_close ((u32) accept_sid);
2960 func_str = "ldp_fd_from_sid";
2962 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2963 "accept sid %u (0x%x), ep %p, flags 0x%x",
2964 getpid (), listen_fd, listen_fd,
2965 func_str, accept_sid, accept_sid, ep, flags);
2966 rv = ldp_fd_alloc ((u32) accept_sid);
2969 (void) vppcom_session_close ((u32) accept_sid);
2978 func_str = "libc_accept4";
2981 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2982 "addr %p, addr_len %p, flags 0x%x",
2983 getpid (), listen_fd, listen_fd, func_str,
2984 addr, addr_len, flags);
2986 rv = libc_accept4 (listen_fd, addr, addr_len, flags);
2993 int errno_val = errno;
2995 clib_warning ("LDP<%d>: ERROR: listen fd %d (0x%x): %s() failed! "
2996 "rv %d, errno = %d", getpid (), listen_fd,
2997 listen_fd, func_str, rv, errno_val);
3001 clib_warning ("LDP<%d>: listen fd %d (0x%x): returning %d (0x%x)",
3002 getpid (), listen_fd, listen_fd, rv, rv);
3008 accept4 (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len,
3011 return ldp_accept4 (fd, addr, addr_len, flags);
3015 accept (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
3017 return ldp_accept4 (fd, addr, addr_len, 0);
3021 shutdown (int fd, int how)
3024 const char *func_str;
3025 u32 sid = ldp_sid_from_fd (fd);
3027 if ((errno = -ldp_init ()))
3030 if (sid != INVALID_SESSION_ID)
3032 func_str = "vppcom_session_close[TODO]";
3037 func_str = "libc_shutdown";
3040 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): how %d",
3041 getpid (), fd, fd, func_str, how);
3043 rv = libc_shutdown (fd, how);
3050 int errno_val = errno;
3052 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
3053 "rv %d, errno = %d", getpid (), fd, fd,
3054 func_str, rv, errno_val);
3058 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
3059 getpid (), fd, fd, rv, rv);
3065 epoll_create1 (int flags)
3067 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
3068 const char *func_str;
3071 if ((errno = -ldp_init ()))
3074 if (ldp->vcl_needs_real_epoll)
3076 rv = libc_epoll_create1 (flags);
3077 ldp->vcl_needs_real_epoll = 0;
3078 ldpw->vcl_mq_epfd = rv;
3079 LDBG (0, "LDP<%d>: created vcl epfd %u", getpid (), rv);
3082 func_str = "vppcom_epoll_create";
3084 LDBG (1, "LDP<%d>: calling %s()", getpid (), func_str);
3086 rv = vppcom_epoll_create ();
3088 if (PREDICT_FALSE (rv < 0))
3094 rv = ldp_fd_alloc ((u32) rv);
3100 int errno_val = errno;
3102 clib_warning ("LDP<%d>: ERROR: %s() failed! "
3103 "rv %d, errno = %d",
3104 getpid (), func_str, rv, errno_val);
3108 clib_warning ("LDP<%d>: returning epfd %d (0x%x)", getpid (), rv, rv);
3114 epoll_create (int size)
3116 return epoll_create1 (0);
3120 epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
3122 u32 vep_idx = ldp_sid_from_fd (epfd), sid;
3123 const char *func_str;
3126 if ((errno = -ldp_init ()))
3129 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
3131 /* The LDP epoll_create1 always creates VCL epfd's.
3132 * The app should never have a kernel base epoll fd unless it
3133 * was acquired outside of the LD_PRELOAD process context.
3134 * In any case, if we get one, punt it to libc_epoll_ctl.
3136 func_str = "libc_epoll_ctl";
3138 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): op %d, fd %d (0x%x),"
3139 " event %p", getpid (), epfd, epfd, func_str, op, fd, fd, event);
3141 rv = libc_epoll_ctl (epfd, op, fd, event);
3145 sid = ldp_sid_from_fd (fd);
3147 LDBG (0, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x), sid %d (0x%x)",
3148 getpid (), epfd, epfd, vep_idx, vep_idx, sid, sid);
3150 if (sid != INVALID_SESSION_ID)
3152 func_str = "vppcom_epoll_ctl";
3154 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3155 " op %d, sid %u (0x%x), event %p", getpid (), epfd, epfd,
3156 func_str, vep_idx, vep_idx, sid, sid, event);
3158 rv = vppcom_epoll_ctl (vep_idx, op, sid, event);
3159 if (rv != VPPCOM_OK)
3168 u32 size = sizeof (epfd);
3170 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
3171 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0,
3173 LDBG (1, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): %s() "
3174 "returned libc_epfd %d (0x%x)", getpid (), epfd, epfd,
3175 vep_idx, vep_idx, func_str, libc_epfd, libc_epfd);
3179 func_str = "libc_epoll_create1";
3181 LDBG (1, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): "
3182 "calling %s(): EPOLL_CLOEXEC", getpid (), epfd, epfd,
3183 vep_idx, vep_idx, func_str);
3185 libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
3192 func_str = "vppcom_session_attr[SET_LIBC_EPFD]";
3193 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3194 " VPPCOM_ATTR_SET_LIBC_EPFD, libc_epfd %d (0x%x), size %d",
3195 getpid (), epfd, epfd, func_str, vep_idx, vep_idx, libc_epfd,
3198 rv = vppcom_session_attr (vep_idx, VPPCOM_ATTR_SET_LIBC_EPFD,
3207 else if (PREDICT_FALSE (libc_epfd < 0))
3214 func_str = "libc_epoll_ctl";
3216 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): libc_epfd %d (0x%x), "
3217 "op %d, fd %d (0x%x), event %p", getpid (), epfd, epfd, func_str,
3218 libc_epfd, libc_epfd, op, fd, fd, event);
3220 rv = libc_epoll_ctl (libc_epfd, op, fd, event);
3228 int errno_val = errno;
3230 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
3231 "rv %d, errno = %d", getpid (), fd, fd,
3232 func_str, rv, errno_val);
3236 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
3237 getpid (), fd, fd, rv, rv);
3243 ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
3244 int timeout, const sigset_t * sigmask)
3246 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
3247 double time_to_wait = (double) 0, time_out, now = 0;
3248 u32 vep_idx = ldp_sid_from_fd (epfd);
3249 int libc_epfd, rv = 0;
3250 const char *func_str;
3252 if ((errno = -ldp_init ()))
3255 if (PREDICT_FALSE (!events || (timeout < -1)))
3261 if (epfd == ldpw->vcl_mq_epfd)
3262 return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
3264 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
3266 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): bad vep_idx %d (0x%x)!",
3267 getpid (), epfd, epfd, vep_idx, vep_idx);
3272 time_to_wait = ((timeout >= 0) ? (double) timeout : 0);
3273 time_out = clib_time_now (&ldpw->clib_time) + time_to_wait;
3275 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
3276 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
3277 if (PREDICT_FALSE (libc_epfd < 0))
3284 LDBG (2, "LDP<%d>: epfd %d (0x%x): vep_idx %d (0x%x), libc_epfd %d (0x%x), "
3285 "events %p, maxevents %d, timeout %d, sigmask %p: time_to_wait %.02f",
3286 getpid (), epfd, epfd, vep_idx, vep_idx, libc_epfd, libc_epfd, events,
3287 maxevents, timeout, sigmask, time_to_wait, time_out);
3290 if (!ldpw->epoll_wait_vcl)
3292 func_str = "vppcom_epoll_wait";
3294 LDBG (3, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3295 " events %p, maxevents %d", getpid (), epfd, epfd, func_str,
3296 vep_idx, vep_idx, events, maxevents);
3298 rv = vppcom_epoll_wait (vep_idx, events, maxevents, 0);
3301 ldpw->epoll_wait_vcl = 1;
3312 ldpw->epoll_wait_vcl = 0;
3316 func_str = "libc_epoll_pwait";
3318 LDBG (3, "LDP<%d>: epfd %d (0x%x): calling %s(): libc_epfd %d "
3319 "(0x%x), events %p, maxevents %d, sigmask %p", getpid (),
3320 epfd, epfd, func_str, libc_epfd, libc_epfd, events,
3321 maxevents, sigmask);
3323 rv = libc_epoll_pwait (libc_epfd, events, maxevents, 1, sigmask);
3329 now = clib_time_now (&ldpw->clib_time);
3331 while (now < time_out);
3340 int errno_val = errno;
3342 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): %s() failed! "
3343 "rv %d, errno = %d", getpid (), epfd, epfd,
3344 func_str, rv, errno_val);
3348 clib_warning ("LDP<%d>: epfd %d (0x%x): returning %d (0x%x)",
3349 getpid (), epfd, epfd, rv, rv);
3355 epoll_pwait (int epfd, struct epoll_event *events,
3356 int maxevents, int timeout, const sigset_t * sigmask)
3358 return ldp_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
3362 epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
3364 return ldp_epoll_pwait (epfd, events, maxevents, timeout, NULL);
3368 poll (struct pollfd *fds, nfds_t nfds, int timeout)
3370 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
3371 const char *func_str = __func__;
3372 int rv, i, n_revents = 0;
3375 double wait_for_time;
3377 LDBG (3, "LDP<%d>: fds %p, nfds %d, timeout %d", getpid (), fds, nfds,
3381 wait_for_time = (f64) timeout / 1000;
3385 for (i = 0; i < nfds; i++)
3390 LDBG (3, "LDP<%d>: fds[%d] fd %d (0x%0x) events = 0x%x revents = 0x%x",
3391 getpid (), i, fds[i].fd, fds[i].fd, fds[i].events,
3394 sid = ldp_sid_from_fd (fds[i].fd);
3395 if (sid != INVALID_SESSION_ID)
3397 fds[i].fd = -fds[i].fd;
3398 vec_add2 (ldpw->vcl_poll, vp, 1);
3401 vp->events = fds[i].events;
3402 #ifdef __USE_XOPEN2K
3403 if (fds[i].events & POLLRDNORM)
3404 vp->events |= POLLIN;
3405 if (fds[i].events & POLLWRNORM)
3406 vp->events |= POLLOUT;
3408 vp->revents = fds[i].revents;
3412 vec_add1 (ldpw->libc_poll, fds[i]);
3413 vec_add1 (ldpw->libc_poll_idxs, i);
3419 if (vec_len (ldpw->vcl_poll))
3421 func_str = "vppcom_poll";
3423 LDBG (3, "LDP<%d>: calling %s(): vcl_poll %p, n_sids %u (0x%x): "
3424 "n_libc_fds %u", getpid (), func_str, ldpw->vcl_poll,
3425 vec_len (ldpw->vcl_poll), vec_len (ldpw->vcl_poll),
3426 vec_len (ldpw->libc_poll));
3428 rv = vppcom_poll (ldpw->vcl_poll, vec_len (ldpw->vcl_poll), 0);
3439 if (vec_len (ldpw->libc_poll))
3441 func_str = "libc_poll";
3443 LDBG (3, "LDP<%d>: calling %s(): fds %p, nfds %u: n_sids %u",
3444 getpid (), fds, nfds, vec_len (ldpw->vcl_poll));
3446 rv = libc_poll (ldpw->libc_poll, vec_len (ldpw->libc_poll), 0);
3459 while ((wait_for_time == -1) ||
3460 (clib_time_now (&ldpw->clib_time) < wait_for_time));
3464 vec_foreach (vp, ldpw->vcl_poll)
3466 fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd;
3467 fds[vp->fds_ndx].revents = vp->revents;
3468 #ifdef __USE_XOPEN2K
3469 if ((fds[vp->fds_ndx].revents & POLLIN) &&
3470 (fds[vp->fds_ndx].events & POLLRDNORM))
3471 fds[vp->fds_ndx].revents |= POLLRDNORM;
3472 if ((fds[vp->fds_ndx].revents & POLLOUT) &&
3473 (fds[vp->fds_ndx].events & POLLWRNORM))
3474 fds[vp->fds_ndx].revents |= POLLWRNORM;
3477 vec_reset_length (ldpw->vcl_poll);
3479 for (i = 0; i < vec_len (ldpw->libc_poll); i++)
3481 fds[ldpw->libc_poll_idxs[i]].revents = ldpw->libc_poll[i].revents;
3483 vec_reset_length (ldpw->libc_poll_idxs);
3484 vec_reset_length (ldpw->libc_poll);
3490 int errno_val = errno;
3492 clib_warning ("LDP<%d>: ERROR: %s() failed! "
3493 "rv %d, errno = %d", getpid (),
3494 func_str, rv, errno_val);
3499 clib_warning ("LDP<%d>: returning %d (0x%x): n_sids %u, "
3500 "n_libc_fds %d", getpid (), rv, rv,
3501 vec_len (ldpw->vcl_poll), vec_len (ldpw->libc_poll));
3503 for (i = 0; i < nfds; i++)
3508 clib_warning ("LDP<%d>: fds[%d].fd %d (0x%0x), "
3509 ".events = 0x%x, .revents = 0x%x",
3510 getpid (), i, fds[i].fd, fds[i].fd,
3511 fds[i].events, fds[i].revents);
3522 ppoll (struct pollfd *fds, nfds_t nfds,
3523 const struct timespec *timeout, const sigset_t * sigmask)
3525 if ((errno = -ldp_init ()))
3528 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
3536 void CONSTRUCTOR_ATTRIBUTE ldp_constructor (void);
3538 void DESTRUCTOR_ATTRIBUTE ldp_destructor (void);
3541 * This function is called when the library is loaded
3544 ldp_constructor (void)
3546 swrap_constructor ();
3547 if (ldp_init () != 0)
3548 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
3550 else if (LDP_DEBUG > 0)
3551 clib_warning ("LDP<%d>: LDP constructor: done!\n", getpid ());
3555 * This function is called when the library is unloaded
3558 ldp_destructor (void)
3560 swrap_destructor ();
3564 /* Don't use clib_warning() here because that calls writev()
3565 * which will call ldp_init().
3568 printf ("%s:%d: LDP<%d>: LDP destructor: done!\n",
3569 __func__, __LINE__, getpid ());
3574 * fd.io coding-style-patch-verification: ON
3577 * eval: (c-set-style "gnu")