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 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_init: vppcom_app_create()"
262 " failed! rv = %d (%s)\n",
263 getpid (), rv, vppcom_retval_str (rv));
267 ldp->vcl_needs_real_epoll = 0;
268 pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
269 ldpw = ldp_worker_get_current ();
271 char *env_var_str = getenv (LDP_ENV_DEBUG);
275 if (sscanf (env_var_str, "%u", &tmp) != 1)
276 clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level specified in"
277 " the env var " LDP_ENV_DEBUG " (%s)!", getpid (),
282 LDBG (0, "LDP<%d>: configured LDP debug level (%u) from env var "
283 LDP_ENV_DEBUG "!", getpid (), ldp->debug);
287 env_var_str = getenv (LDP_ENV_APP_NAME);
290 ldp_set_app_name (env_var_str);
291 LDBG (0, "LDP<%d>: configured LDP app name (%s) from the env var "
292 LDP_ENV_APP_NAME "!", getpid (), ldp->app_name);
295 env_var_str = getenv (LDP_ENV_SID_BIT);
299 if (sscanf (env_var_str, "%u", &sb) != 1)
301 clib_warning ("LDP<%d>: WARNING: Invalid LDP sid bit specified in"
302 " the env var " LDP_ENV_SID_BIT " (%s)! sid bit "
303 "value %d (0x%x)", getpid (), env_var_str,
304 ldp->sid_bit_val, ldp->sid_bit_val);
306 else if (sb < LDP_SID_BIT_MIN)
308 ldp->sid_bit_val = (1 << LDP_SID_BIT_MIN);
309 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
311 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
312 " env var " LDP_ENV_SID_BIT " (%s) is too small. "
313 "Using LDP_SID_BIT_MIN (%d)! sid bit value %d (0x%x)",
314 getpid (), sb, env_var_str, LDP_SID_BIT_MIN,
315 ldp->sid_bit_val, ldp->sid_bit_val);
317 else if (sb > LDP_SID_BIT_MAX)
319 ldp->sid_bit_val = (1 << LDP_SID_BIT_MAX);
320 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
322 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
323 " env var " LDP_ENV_SID_BIT " (%s) is too big. Using"
324 " LDP_SID_BIT_MAX (%d)! sid bit value %d (0x%x)",
325 getpid (), sb, env_var_str, LDP_SID_BIT_MAX,
326 ldp->sid_bit_val, ldp->sid_bit_val);
330 ldp->sid_bit_val = (1 << sb);
331 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
333 LDBG (0, "LDP<%d>: configured LDP sid bit (%u) from "
334 LDP_ENV_SID_BIT "! sid bit value %d (0x%x)", getpid (), sb,
335 ldp->sid_bit_val, ldp->sid_bit_val);
339 clib_time_init (&ldpw->clib_time);
340 clib_rwlock_init (&ldp->fd_table_lock);
341 LDBG (0, "LDP<%d>: LDP initialization: done!", getpid ());
350 const char *func_str;
351 u32 sid = ldp_sid_from_fd (fd);
353 if ((errno = -ldp_init ()))
356 if (sid != INVALID_SESSION_ID)
360 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
361 epfd = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
364 func_str = "libc_close";
366 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): epfd %u (0x%x)",
367 getpid (), fd, fd, func_str, epfd, epfd);
369 rv = libc_close (epfd);
372 u32 size = sizeof (epfd);
375 (void) vppcom_session_attr (sid, VPPCOM_ATTR_SET_LIBC_EPFD,
379 else if (PREDICT_FALSE (epfd < 0))
386 func_str = "vppcom_session_close";
388 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
389 getpid (), fd, fd, func_str, sid, sid);
391 rv = vppcom_session_close (sid);
397 ldp_fd_free_w_sid (sid);
401 func_str = "libc_close";
403 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s()", getpid (), fd, fd,
406 rv = libc_close (fd);
414 int errno_val = errno;
416 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
417 "rv %d, errno = %d", getpid (), fd, fd,
418 func_str, rv, errno_val);
422 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
423 getpid (), fd, fd, rv, rv);
429 read (int fd, void *buf, size_t nbytes)
432 const char *func_str;
433 u32 sid = ldp_sid_from_fd (fd);
435 if ((errno = -ldp_init ()))
438 if (sid != INVALID_SESSION_ID)
440 func_str = "vppcom_session_read";
443 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
444 "sid %u (0x%x), buf %p, nbytes %u", getpid (),
445 fd, fd, func_str, sid, sid, buf, nbytes);
447 size = vppcom_session_read (sid, buf, nbytes);
456 func_str = "libc_read";
459 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
460 "buf %p, nbytes %u", getpid (),
461 fd, fd, func_str, buf, nbytes);
463 size = libc_read (fd, buf, nbytes);
470 int errno_val = errno;
472 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
473 "rv %d, errno = %d", getpid (), fd, fd,
474 func_str, size, errno_val);
478 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
479 getpid (), fd, fd, size, size);
485 readv (int fd, const struct iovec * iov, int iovcnt)
487 const char *func_str;
489 u32 sid = ldp_sid_from_fd (fd);
490 int rv = 0, i, total = 0;
492 if ((errno = -ldp_init ()))
495 if (sid != INVALID_SESSION_ID)
497 func_str = "vppcom_session_read";
500 for (i = 0; i < iovcnt; ++i)
503 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s() [%d]: "
504 "sid %u (0x%x), iov %p, iovcnt %d, total %d",
505 getpid (), fd, fd, func_str, i, sid, sid,
508 rv = vppcom_session_read (sid, iov[i].iov_base, iov[i].iov_len);
514 if (rv < iov[i].iov_len)
517 clib_warning ("LDP<%d>: fd %d (0x%x): "
518 "rv (%d) < iov[%d].iov_len (%d)",
519 getpid (), fd, fd, rv, i,
526 while ((rv >= 0) && (total == 0));
538 func_str = "libc_readv";
541 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
542 "iov %p, iovcnt %d", getpid (), fd, fd, iov, iovcnt);
544 size = libc_readv (fd, iov, iovcnt);
551 int errno_val = errno;
553 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
554 "rv %d, errno = %d", getpid (), fd, fd,
555 func_str, size, errno_val);
559 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
560 getpid (), fd, fd, size, size);
566 write (int fd, const void *buf, size_t nbytes)
568 const char *func_str;
570 u32 sid = ldp_sid_from_fd (fd);
572 if ((errno = -ldp_init ()))
575 if (sid != INVALID_SESSION_ID)
577 func_str = "vppcom_session_write";
580 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
581 "sid %u (0x%x), buf %p, nbytes %u", getpid (),
582 fd, fd, func_str, sid, sid, buf, nbytes);
584 size = vppcom_session_write (sid, (void *) buf, nbytes);
593 func_str = "libc_write";
596 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
597 "buf %p, nbytes %u", getpid (),
598 fd, fd, func_str, buf, nbytes);
600 size = libc_write (fd, buf, nbytes);
607 int errno_val = errno;
609 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
610 "rv %d, errno = %d", getpid (), fd, fd,
611 func_str, size, errno_val);
615 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
616 getpid (), fd, fd, size, size);
622 writev (int fd, const struct iovec * iov, int iovcnt)
624 const char *func_str;
625 ssize_t size = 0, total = 0;
626 u32 sid = ldp_sid_from_fd (fd);
630 * Use [f]printf() instead of clib_warning() to prevent recursion SIGSEGV.
633 if ((errno = -ldp_init ()))
636 if (sid != INVALID_SESSION_ID)
638 func_str = "vppcom_session_write";
641 for (i = 0; i < iovcnt; ++i)
644 printf ("%s:%d: LDP<%d>: fd %d (0x%x): calling %s() [%d]: "
645 "sid %u (0x%x), buf %p, nbytes %ld, total %ld",
646 __func__, __LINE__, getpid (), fd, fd, func_str,
647 i, sid, sid, iov[i].iov_base, iov[i].iov_len, total);
649 rv = vppcom_session_write (sid, iov[i].iov_base,
656 if (rv < iov[i].iov_len)
659 printf ("%s:%d: LDP<%d>: fd %d (0x%x): "
660 "rv (%d) < iov[%d].iov_len (%ld)",
661 __func__, __LINE__, getpid (), fd, fd,
662 rv, i, iov[i].iov_len);
668 while ((rv >= 0) && (total == 0));
680 func_str = "libc_writev";
683 printf ("%s:%d: LDP<%d>: fd %d (0x%x): calling %s(): "
684 "iov %p, iovcnt %d\n", __func__, __LINE__, getpid (),
685 fd, fd, func_str, iov, iovcnt);
687 size = libc_writev (fd, iov, iovcnt);
694 int errno_val = errno;
697 "%s:%d: LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
698 "rv %ld, errno = %d\n", __func__, __LINE__, getpid (), fd,
699 fd, func_str, size, errno_val);
703 printf ("%s:%d: LDP<%d>: fd %d (0x%x): returning %ld\n",
704 __func__, __LINE__, getpid (), fd, fd, size);
710 fcntl (int fd, int cmd, ...)
712 const char *func_str = __func__;
715 u32 sid = ldp_sid_from_fd (fd);
717 if ((errno = -ldp_init ()))
721 if (sid != INVALID_SESSION_ID)
723 int flags = va_arg (ap, int);
726 size = sizeof (flags);
731 func_str = "vppcom_session_attr[SET_FLAGS]";
732 LDBG (2, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x) "
733 "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid,
734 sid, flags, flags, size);
736 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
741 func_str = "vppcom_session_attr[GET_FLAGS]";
742 LDBG (2, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
743 "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid,
744 sid, flags, flags, size);
746 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
750 LDBG (2, "LDP<%d>: fd %d (0x%x), cmd %d (F_GETFL): %s() "
751 "returned flags %d (0x%x)", getpid (), fd, fd, cmd,
752 func_str, flags, flags);
757 /* TODO handle this */
758 LDBG (0, "F_SETFD ignored flags %u", flags);
773 func_str = "libc_vfcntl";
776 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
777 getpid (), fd, fd, func_str, cmd);
779 rv = libc_vfcntl (fd, cmd, ap);
788 int errno_val = errno;
790 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
791 "rv %d, errno = %d", getpid (), fd, fd,
792 func_str, rv, errno_val);
796 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
797 getpid (), fd, fd, rv, rv);
803 ioctl (int fd, unsigned long int cmd, ...)
805 const char *func_str;
808 u32 sid = ldp_sid_from_fd (fd);
810 if ((errno = -ldp_init ()))
814 if (sid != INVALID_SESSION_ID)
816 func_str = "vppcom_session_attr[GET_NREAD]";
823 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
824 getpid (), fd, fd, func_str, sid, sid);
826 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NREAD, 0, 0);
831 u32 flags = va_arg (ap, int) ? O_NONBLOCK : 0;
832 u32 size = sizeof (flags);
834 /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than
835 * non-blocking, the flags should be read here and merged
839 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
840 "sid %u (0x%x), flags %d (0x%x), size %d",
841 getpid (), fd, fd, func_str, sid, sid,
844 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
861 func_str = "libc_vioctl";
864 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
865 getpid (), fd, fd, func_str, cmd);
867 rv = libc_vioctl (fd, cmd, ap);
874 int errno_val = errno;
876 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
877 "rv %d, errno = %d", getpid (), fd, fd,
878 func_str, rv, errno_val);
882 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
883 getpid (), fd, fd, rv, rv);
890 ldp_pselect (int nfds, fd_set * __restrict readfds,
891 fd_set * __restrict writefds,
892 fd_set * __restrict exceptfds,
893 const struct timespec *__restrict timeout,
894 const __sigset_t * __restrict sigmask)
896 uword sid_bits, sid_bits_set, libc_bits, libc_bits_set;
897 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
898 u32 minbits = clib_max (nfds, BITS (uword)), sid;
899 char *func_str = "##";
911 time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
912 (f64) 0 : (f64) timeout->tv_sec +
913 (f64) timeout->tv_nsec / (f64) 1000000000;
915 /* select as fine grained sleep */
918 LDBG (3, "LDP<%d>: sleeping for %.02f seconds", getpid (),
921 time_out += clib_time_now (&ldpw->clib_time);
922 while (clib_time_now (&ldpw->clib_time) < time_out)
936 if (nfds <= ldp->sid_bit_val)
938 func_str = "libc_pselect";
940 LDBG (3, "LDP<%d>: calling %s(): nfds %d, readfds %p, writefds %p, "
941 "exceptfds %p, timeout %p, sigmask %p", getpid (), func_str, nfds,
942 readfds, writefds, exceptfds, timeout, sigmask);
944 rv = libc_pselect (nfds, readfds, writefds, exceptfds,
949 if (PREDICT_FALSE (ldp->sid_bit_val > FD_SETSIZE / 2))
951 clib_warning ("LDP<%d>: ERROR: LDP sid bit value %d (0x%x) > "
952 "FD_SETSIZE/2 %d (0x%x)!", getpid (),
953 ldp->sid_bit_val, ldp->sid_bit_val,
954 FD_SETSIZE / 2, FD_SETSIZE / 2);
959 sid_bits = libc_bits = 0;
960 u32 n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0);
963 clib_bitmap_validate (ldpw->sid_rd_bitmap, minbits);
964 clib_bitmap_validate (ldpw->libc_rd_bitmap, minbits);
965 clib_bitmap_validate (ldpw->rd_bitmap, minbits);
966 clib_memcpy_fast (ldpw->rd_bitmap, readfds, n_bytes);
967 memset (readfds, 0, n_bytes);
970 clib_bitmap_foreach (fd, ldpw->rd_bitmap, ({
973 sid = ldp_sid_from_fd (fd);
974 LDBG (3, "LDP<%d>: readfds: fd %d (0x%x), sid %u (0x%x)",
975 getpid (), fd, fd, sid, sid);
976 if (sid == INVALID_SESSION_ID)
977 clib_bitmap_set_no_check (ldpw->libc_rd_bitmap, fd, 1);
979 clib_bitmap_set_no_check (ldpw->sid_rd_bitmap,
980 vppcom_session_index (sid), 1);
984 sid_bits_set = clib_bitmap_last_set (ldpw->sid_rd_bitmap) + 1;
985 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
987 libc_bits_set = clib_bitmap_last_set (ldpw->libc_rd_bitmap) + 1;
988 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
990 LDBG (3, "LDP<%d>: readfds: sid_bits_set %d, sid_bits %d, "
991 "libc_bits_set %d, libc_bits %d", getpid (), sid_bits_set,
992 sid_bits, libc_bits_set, libc_bits);
996 clib_bitmap_validate (ldpw->sid_wr_bitmap, minbits);
997 clib_bitmap_validate (ldpw->libc_wr_bitmap, minbits);
998 clib_bitmap_validate (ldpw->wr_bitmap, minbits);
999 clib_memcpy_fast (ldpw->wr_bitmap, writefds, n_bytes);
1000 memset (writefds, 0, n_bytes);
1003 clib_bitmap_foreach (fd, ldpw->wr_bitmap, ({
1006 sid = ldp_sid_from_fd (fd);
1007 LDBG (3, "LDP<%d>: writefds: fd %d (0x%x), sid %u (0x%x)",
1008 getpid (), fd, fd, sid, sid);
1009 if (sid == INVALID_SESSION_ID)
1010 clib_bitmap_set_no_check (ldpw->libc_wr_bitmap, fd, 1);
1012 clib_bitmap_set_no_check (ldpw->sid_wr_bitmap,
1013 vppcom_session_index (sid), 1);
1017 sid_bits_set = clib_bitmap_last_set (ldpw->sid_wr_bitmap) + 1;
1018 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
1020 libc_bits_set = clib_bitmap_last_set (ldpw->libc_wr_bitmap) + 1;
1021 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
1023 LDBG (3, "LDP<%d>: writefds: sid_bits_set %d, sid_bits %d, "
1024 "libc_bits_set %d, libc_bits %d", getpid (),
1025 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
1029 clib_bitmap_validate (ldpw->sid_ex_bitmap, minbits);
1030 clib_bitmap_validate (ldpw->libc_ex_bitmap, minbits);
1031 clib_bitmap_validate (ldpw->ex_bitmap, minbits);
1032 clib_memcpy_fast (ldpw->ex_bitmap, exceptfds, n_bytes);
1033 memset (exceptfds, 0, n_bytes);
1036 clib_bitmap_foreach (fd, ldpw->ex_bitmap, ({
1039 sid = ldp_sid_from_fd (fd);
1040 LDBG (3, "LDP<%d>: exceptfds: fd %d (0x%x), sid %u (0x%x)",
1041 getpid (), fd, fd, sid, sid);
1042 if (sid == INVALID_SESSION_ID)
1043 clib_bitmap_set_no_check (ldpw->libc_ex_bitmap, fd, 1);
1045 clib_bitmap_set_no_check (ldpw->sid_ex_bitmap,
1046 vppcom_session_index (sid), 1);
1050 sid_bits_set = clib_bitmap_last_set (ldpw->sid_ex_bitmap) + 1;
1051 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
1053 libc_bits_set = clib_bitmap_last_set (ldpw->libc_ex_bitmap) + 1;
1054 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
1056 LDBG (3, "LDP<%d>: exceptfds: sid_bits_set %d, sid_bits %d, "
1057 "libc_bits_set %d, libc_bits %d", getpid (),
1058 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
1061 if (PREDICT_FALSE (!sid_bits && !libc_bits))
1072 if (!ldpw->select_vcl)
1074 func_str = "vppcom_select";
1077 clib_memcpy_fast (ldpw->rd_bitmap, ldpw->sid_rd_bitmap,
1078 vec_len (ldpw->rd_bitmap) *
1079 sizeof (clib_bitmap_t));
1081 clib_memcpy_fast (ldpw->wr_bitmap, ldpw->sid_wr_bitmap,
1082 vec_len (ldpw->wr_bitmap) *
1083 sizeof (clib_bitmap_t));
1085 clib_memcpy_fast (ldpw->ex_bitmap, ldpw->sid_ex_bitmap,
1086 vec_len (ldpw->ex_bitmap) *
1087 sizeof (clib_bitmap_t));
1089 rv = vppcom_select (sid_bits,
1090 readfds ? ldpw->rd_bitmap : NULL,
1091 writefds ? ldpw->wr_bitmap : NULL,
1092 exceptfds ? ldpw->ex_bitmap : NULL, 0);
1103 clib_bitmap_foreach (sid, ldpw->rd_bitmap,
1105 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
1106 if (PREDICT_FALSE (fd < 0))
1112 FD_SET (fd, readfds);
1119 clib_bitmap_foreach (sid, ldpw->wr_bitmap,
1121 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
1122 if (PREDICT_FALSE (fd < 0))
1128 FD_SET (fd, writefds);
1135 clib_bitmap_foreach (sid, ldpw->ex_bitmap,
1137 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
1138 if (PREDICT_FALSE (fd < 0))
1144 FD_SET (fd, exceptfds);
1148 ldpw->select_vcl = 1;
1153 ldpw->select_vcl = 0;
1157 struct timespec tspec;
1159 func_str = "libc_pselect";
1162 clib_memcpy_fast (readfds, ldpw->libc_rd_bitmap,
1163 vec_len (ldpw->rd_bitmap) *
1164 sizeof (clib_bitmap_t));
1166 clib_memcpy_fast (writefds, ldpw->libc_wr_bitmap,
1167 vec_len (ldpw->wr_bitmap) *
1168 sizeof (clib_bitmap_t));
1170 clib_memcpy_fast (exceptfds, ldpw->libc_ex_bitmap,
1171 vec_len (ldpw->ex_bitmap) *
1172 sizeof (clib_bitmap_t));
1173 tspec.tv_sec = tspec.tv_nsec = 0;
1174 rv = libc_pselect (libc_bits,
1175 readfds ? readfds : NULL,
1176 writefds ? writefds : NULL,
1177 exceptfds ? exceptfds : NULL, &tspec, sigmask);
1182 while ((time_out == -1) || (clib_time_now (&ldpw->clib_time) < time_out));
1186 /* TBD: set timeout to amount of time left */
1187 clib_bitmap_zero (ldpw->rd_bitmap);
1188 clib_bitmap_zero (ldpw->sid_rd_bitmap);
1189 clib_bitmap_zero (ldpw->libc_rd_bitmap);
1190 clib_bitmap_zero (ldpw->wr_bitmap);
1191 clib_bitmap_zero (ldpw->sid_wr_bitmap);
1192 clib_bitmap_zero (ldpw->libc_wr_bitmap);
1193 clib_bitmap_zero (ldpw->ex_bitmap);
1194 clib_bitmap_zero (ldpw->sid_ex_bitmap);
1195 clib_bitmap_zero (ldpw->libc_ex_bitmap);
1201 int errno_val = errno;
1203 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1204 "rv %d, errno = %d", getpid (),
1205 func_str, rv, errno_val);
1209 clib_warning ("LDP<%d>: returning %d (0x%x)", getpid (), rv, rv);
1215 select (int nfds, fd_set * __restrict readfds,
1216 fd_set * __restrict writefds,
1217 fd_set * __restrict exceptfds, struct timeval *__restrict timeout)
1219 struct timespec tspec;
1223 tspec.tv_sec = timeout->tv_sec;
1224 tspec.tv_nsec = timeout->tv_usec * 1000;
1226 return ldp_pselect (nfds, readfds, writefds, exceptfds,
1227 timeout ? &tspec : NULL, NULL);
1230 #ifdef __USE_XOPEN2K
1232 pselect (int nfds, fd_set * __restrict readfds,
1233 fd_set * __restrict writefds,
1234 fd_set * __restrict exceptfds,
1235 const struct timespec *__restrict timeout,
1236 const __sigset_t * __restrict sigmask)
1238 return ldp_pselect (nfds, readfds, writefds, exceptfds, timeout, 0);
1243 socket (int domain, int type, int protocol)
1245 const char *func_str;
1247 u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
1248 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1250 if ((errno = -ldp_init ()))
1253 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1254 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
1257 u8 proto = ((sock_type == SOCK_DGRAM) ?
1258 VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
1260 func_str = "vppcom_session_create";
1262 LDBG (0, "LDP<%d>: : calling %s(): proto %u (%s), is_nonblocking %u",
1263 getpid (), func_str, proto, vppcom_proto_str (proto),
1266 sid = vppcom_session_create (proto, is_nonblocking);
1274 func_str = "ldp_fd_from_sid";
1275 rv = ldp_fd_alloc (sid);
1278 (void) vppcom_session_close (sid);
1286 func_str = "libc_socket";
1288 LDBG (0, "LDP<%d>: : calling %s()", getpid (), func_str);
1290 rv = libc_socket (domain, type, protocol);
1297 int errno_val = errno;
1299 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1300 "rv %d, errno = %d",
1301 getpid (), func_str, rv, errno_val);
1305 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1311 * Create two new sockets, of type TYPE in domain DOMAIN and using
1312 * protocol PROTOCOL, which are connected to each other, and put file
1313 * descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
1314 * one will be chosen automatically.
1315 * Returns 0 on success, -1 for errors.
1318 socketpair (int domain, int type, int protocol, int fds[2])
1320 const char *func_str;
1322 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1324 if ((errno = -ldp_init ()))
1327 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1328 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
1330 func_str = __func__;
1332 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1338 func_str = "libc_socket";
1340 LDBG (1, "LDP<%d>: : calling %s()", getpid (), func_str);
1342 rv = libc_socketpair (domain, type, protocol, fds);
1349 int errno_val = errno;
1351 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1352 "rv %d, errno = %d",
1353 getpid (), func_str, rv, errno_val);
1357 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1363 bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
1366 const char *func_str;
1367 u32 sid = ldp_sid_from_fd (fd);
1369 if ((errno = -ldp_init ()))
1372 if (sid != INVALID_SESSION_ID)
1376 func_str = "vppcom_session_bind";
1378 switch (addr->sa_family)
1381 if (len != sizeof (struct sockaddr_in))
1384 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1385 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1390 ep.is_ip4 = VPPCOM_IS_IP4;
1391 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1392 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1396 if (len != sizeof (struct sockaddr_in6))
1399 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1400 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1405 ep.is_ip4 = VPPCOM_IS_IP6;
1406 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1407 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
1411 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): "
1412 "Unsupported address family %u!",
1413 getpid (), fd, fd, sid, sid, addr->sa_family);
1414 errno = EAFNOSUPPORT;
1419 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1421 getpid (), fd, fd, func_str, sid, sid, addr, len);
1423 rv = vppcom_session_bind (sid, &ep);
1424 if (rv != VPPCOM_OK)
1432 func_str = "libc_bind";
1435 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1437 getpid (), fd, fd, func_str, addr, len);
1439 rv = libc_bind (fd, addr, len);
1447 int errno_val = errno;
1449 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1450 "rv %d, errno = %d", getpid (), fd, fd,
1451 func_str, rv, errno_val);
1455 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1456 getpid (), fd, fd, rv, rv);
1462 ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
1463 vppcom_endpt_t * ep)
1466 int sa_len, copy_len;
1468 if ((errno = -ldp_init ()))
1471 if (addr && len && ep)
1473 addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6;
1474 switch (addr->sa_family)
1477 ((struct sockaddr_in *) addr)->sin_port = ep->port;
1478 if (*len > sizeof (struct sockaddr_in))
1479 *len = sizeof (struct sockaddr_in);
1480 sa_len = sizeof (struct sockaddr_in) - sizeof (struct in_addr);
1481 copy_len = *len - sa_len;
1483 memcpy (&((struct sockaddr_in *) addr)->sin_addr, ep->ip,
1488 ((struct sockaddr_in6 *) addr)->sin6_port = ep->port;
1489 if (*len > sizeof (struct sockaddr_in6))
1490 *len = sizeof (struct sockaddr_in6);
1491 sa_len = sizeof (struct sockaddr_in6) - sizeof (struct in6_addr);
1492 copy_len = *len - sa_len;
1494 memcpy (((struct sockaddr_in6 *) addr)->sin6_addr.
1495 __in6_u.__u6_addr8, ep->ip, copy_len);
1508 getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
1511 const char *func_str;
1512 u32 sid = ldp_sid_from_fd (fd);
1514 if ((errno = -ldp_init ()))
1517 if (sid != INVALID_SESSION_ID)
1520 u8 addr_buf[sizeof (struct in6_addr)];
1521 u32 size = sizeof (ep);
1524 func_str = "vppcom_session_attr[GET_LCL_ADDR]";
1527 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1529 getpid (), fd, fd, func_str, sid, sid, addr, len);
1531 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
1532 if (rv != VPPCOM_OK)
1539 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
1540 if (rv != VPPCOM_OK)
1549 func_str = "libc_getsockname";
1552 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1554 getpid (), fd, fd, func_str, addr, len);
1556 rv = libc_getsockname (fd, addr, len);
1563 int errno_val = errno;
1565 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1566 "rv %d, errno = %d", getpid (), fd, fd,
1567 func_str, rv, errno_val);
1571 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1572 getpid (), fd, fd, rv, rv);
1578 connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
1581 const char *func_str = __func__;
1582 u32 sid = ldp_sid_from_fd (fd);
1584 if ((errno = -ldp_init ()))
1589 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): NULL addr, len %u",
1590 getpid (), fd, fd, len);
1596 if (sid != INVALID_SESSION_ID)
1600 func_str = "vppcom_session_connect";
1602 switch (addr->sa_family)
1605 if (len != sizeof (struct sockaddr_in))
1608 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1609 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1614 ep.is_ip4 = VPPCOM_IS_IP4;
1615 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1616 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1620 if (len != sizeof (struct sockaddr_in6))
1623 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1624 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1629 ep.is_ip4 = VPPCOM_IS_IP6;
1630 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1631 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
1635 clib_warning ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): "
1636 "Unsupported address family %u!",
1637 getpid (), fd, fd, sid, sid, addr->sa_family);
1638 errno = EAFNOSUPPORT;
1643 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x) "
1645 getpid (), fd, fd, func_str, sid, sid, addr, len);
1647 rv = vppcom_session_connect (sid, &ep);
1648 if (rv != VPPCOM_OK)
1656 func_str = "libc_connect";
1659 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1661 getpid (), fd, fd, func_str, addr, len);
1663 rv = libc_connect (fd, addr, len);
1671 int errno_val = errno;
1673 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1674 "rv %d, errno = %d", getpid (), fd, fd,
1675 func_str, rv, errno_val);
1679 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1680 getpid (), fd, fd, rv, rv);
1686 getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
1689 const char *func_str;
1690 u32 sid = ldp_sid_from_fd (fd);
1692 if ((errno = -ldp_init ()))
1695 if (sid != INVALID_SESSION_ID)
1698 u8 addr_buf[sizeof (struct in6_addr)];
1699 u32 size = sizeof (ep);
1702 func_str = "vppcom_session_attr[GET_PEER_ADDR]";
1705 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1707 getpid (), fd, fd, func_str, sid, sid, addr, len);
1709 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
1710 if (rv != VPPCOM_OK)
1717 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
1718 if (rv != VPPCOM_OK)
1727 func_str = "libc_getpeername";
1730 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1732 getpid (), fd, fd, func_str, addr, len);
1734 rv = libc_getpeername (fd, addr, len);
1741 int errno_val = errno;
1743 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1744 "rv %d, errno = %d", getpid (), fd, fd,
1745 func_str, rv, errno_val);
1749 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1750 getpid (), fd, fd, rv, rv);
1756 send (int fd, const void *buf, size_t n, int flags)
1759 const char *func_str;
1760 u32 sid = ldp_sid_from_fd (fd);
1762 if ((errno = -ldp_init ()))
1765 if (sid != INVALID_SESSION_ID)
1768 func_str = "vppcom_session_sendto";
1771 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1772 "buf %p, n %u, flags 0x%x",
1773 getpid (), fd, fd, func_str, sid, sid, buf, n, flags);
1775 size = vppcom_session_sendto (sid, (void *) buf, n, flags, NULL);
1776 if (size < VPPCOM_OK)
1784 func_str = "libc_send";
1787 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1788 "buf %p, n %u, flags 0x%x",
1789 getpid (), fd, fd, func_str, buf, n, flags);
1791 size = libc_send (fd, buf, n, flags);
1798 int errno_val = errno;
1800 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1801 "rv %d, errno = %d", getpid (), fd, fd,
1802 func_str, size, errno_val);
1806 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1807 getpid (), fd, fd, size, size);
1813 sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
1815 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
1817 const char *func_str;
1818 u32 sid = ldp_sid_from_fd (out_fd);
1820 if ((errno = -ldp_init ()))
1823 if (sid != INVALID_SESSION_ID)
1826 ssize_t results = 0;
1827 size_t n_bytes_left = len;
1828 size_t bytes_to_read;
1832 u32 flags, flags_len = sizeof (flags);
1834 func_str = "vppcom_session_attr[GET_FLAGS]";
1835 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
1837 if (PREDICT_FALSE (rv != VPPCOM_OK))
1839 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1840 "sid %u (0x%x), returned %d (%s)!", getpid (),
1841 out_fd, out_fd, func_str, sid, sid, rv,
1842 vppcom_retval_str (rv));
1844 vec_reset_length (ldpw->io_buffer);
1852 off_t off = lseek (in_fd, *offset, SEEK_SET);
1853 if (PREDICT_FALSE (off == -1))
1857 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1858 "SEEK_SET failed: in_fd %d, offset %p, "
1859 "*offset %ld, rv %ld, errno %d", getpid (),
1860 out_fd, out_fd, in_fd, offset, *offset, off,
1867 ASSERT (off == *offset);
1872 func_str = "vppcom_session_attr[GET_NWRITE]";
1873 size = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NWRITE, 0, 0);
1877 ("LDP<%d>: ERROR: fd %d (0x%x): %s(): sid %u (0x%x), "
1878 "returned %d (%s)!", getpid (), out_fd, out_fd, func_str,
1879 sid, sid, size, vppcom_retval_str (size));
1880 vec_reset_length (ldpw->io_buffer);
1886 bytes_to_read = size;
1889 ("LDP<%d>: fd %d (0x%x): called %s(): sid %u (0x%x), "
1890 "results %ld, n_bytes_left %lu, bytes_to_read %lu", getpid (),
1891 out_fd, out_fd, func_str, sid, sid, results, n_bytes_left,
1894 if (bytes_to_read == 0)
1896 if (flags & O_NONBLOCK)
1901 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1903 getpid (), out_fd, out_fd, sid, sid);
1911 bytes_to_read = clib_min (n_bytes_left, bytes_to_read);
1912 vec_validate (ldpw->io_buffer, bytes_to_read);
1913 nbytes = libc_read (in_fd, ldpw->io_buffer, bytes_to_read);
1916 func_str = "libc_read";
1918 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): in_fd (%d), "
1919 "io_buffer %p, bytes_to_read %lu, rv %d, "
1920 "errno %d", getpid (), out_fd, out_fd, func_str,
1921 in_fd, ldpw->io_buffer, bytes_to_read, nbytes,
1927 vec_reset_length (ldpw->io_buffer);
1933 func_str = "vppcom_session_write";
1936 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1937 "buf %p, nbytes %u: results %d, n_bytes_left %d", getpid (),
1938 out_fd, out_fd, func_str, sid, sid, ldpw->io_buffer, nbytes,
1939 results, n_bytes_left);
1941 size = vppcom_session_write (sid, ldpw->io_buffer, nbytes);
1944 if (size == VPPCOM_EAGAIN)
1946 if (flags & O_NONBLOCK)
1952 ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1953 "EAGAIN", getpid (), out_fd, out_fd, sid, sid);
1963 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s():"
1964 "sid %u, io_buffer %p, nbytes %u "
1966 getpid (), out_fd, out_fd, func_str,
1967 sid, ldpw->io_buffer, nbytes,
1968 size, vppcom_retval_str (size));
1972 vec_reset_length (ldpw->io_buffer);
1981 ASSERT (n_bytes_left >= nbytes);
1982 n_bytes_left = n_bytes_left - nbytes;
1984 while (n_bytes_left > 0);
1987 vec_reset_length (ldpw->io_buffer);
1990 off_t off = lseek (in_fd, *offset, SEEK_SET);
1991 if (PREDICT_FALSE (off == -1))
1995 clib_warning ("LDP<%d>: ERROR: %s(): SEEK_SET failed: "
1996 "in_fd %d, offset %p, *offset %ld, "
1997 "rv %ld, errno %d", getpid (), in_fd,
1998 offset, *offset, off, errno_val);
2004 ASSERT (off == *offset);
2005 *offset += results + 1;
2017 func_str = "libc_send";
2020 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2021 "in_fd %d, offset %p, len %u",
2022 getpid (), out_fd, out_fd, func_str,
2023 in_fd, offset, len);
2025 size = libc_sendfile (out_fd, in_fd, offset, len);
2033 int errno_val = errno;
2035 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2036 "rv %d, errno = %d", getpid (), out_fd, out_fd,
2037 func_str, size, errno_val);
2041 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2042 getpid (), out_fd, out_fd, size, size);
2048 sendfile64 (int out_fd, int in_fd, off_t * offset, size_t len)
2050 return sendfile (out_fd, in_fd, offset, len);
2054 recv (int fd, void *buf, size_t n, int flags)
2057 const char *func_str;
2058 u32 sid = ldp_sid_from_fd (fd);
2060 if ((errno = -ldp_init ()))
2063 if (sid != INVALID_SESSION_ID)
2065 func_str = "vppcom_session_recvfrom";
2068 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2069 "sid %u (0x%x), buf %p, n %u, flags 0x%x", getpid (),
2070 fd, fd, func_str, sid, sid, buf, n, flags);
2072 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
2081 func_str = "libc_recv";
2084 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2085 "buf %p, n %u, flags 0x%x", getpid (),
2086 fd, fd, func_str, buf, n, flags);
2088 size = libc_recv (fd, buf, n, flags);
2095 int errno_val = errno;
2097 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2098 "rv %d, errno = %d", getpid (), fd, fd,
2099 func_str, size, errno_val);
2103 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2104 getpid (), fd, fd, size, size);
2110 sendto (int fd, const void *buf, size_t n, int flags,
2111 __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
2114 const char *func_str = __func__;
2115 u32 sid = ldp_sid_from_fd (fd);
2117 if ((errno = -ldp_init ()))
2120 if (sid != INVALID_SESSION_ID)
2122 vppcom_endpt_t *ep = 0;
2128 switch (addr->sa_family)
2131 ep->is_ip4 = VPPCOM_IS_IP4;
2133 (uint8_t *) & ((const struct sockaddr_in *) addr)->sin_addr;
2135 (uint16_t) ((const struct sockaddr_in *) addr)->sin_port;
2139 ep->is_ip4 = VPPCOM_IS_IP6;
2141 (uint8_t *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
2143 (uint16_t) ((const struct sockaddr_in6 *) addr)->sin6_port;
2147 errno = EAFNOSUPPORT;
2153 func_str = "vppcom_session_sendto";
2156 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2157 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2158 getpid (), fd, fd, func_str, sid, sid, buf, n,
2161 size = vppcom_session_sendto (sid, (void *) buf, n, flags, ep);
2170 func_str = "libc_sendto";
2173 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2174 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2175 getpid (), fd, fd, func_str, buf, n, flags,
2178 size = libc_sendto (fd, buf, n, flags, addr, addr_len);
2186 int errno_val = errno;
2188 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2189 "rv %d, errno = %d", getpid (), fd, fd,
2190 func_str, size, errno_val);
2194 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2195 getpid (), fd, fd, size, size);
2201 recvfrom (int fd, void *__restrict buf, size_t n, int flags,
2202 __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
2205 const char *func_str;
2206 u32 sid = ldp_sid_from_fd (fd);
2208 if ((errno = -ldp_init ()))
2211 if (sid != INVALID_SESSION_ID)
2214 u8 src_addr[sizeof (struct sockaddr_in6)];
2216 func_str = "vppcom_session_recvfrom";
2219 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2220 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2221 getpid (), fd, fd, func_str, sid, sid, buf, n,
2226 size = vppcom_session_recvfrom (sid, buf, n, flags, &ep);
2229 size = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
2232 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
2242 func_str = "libc_recvfrom";
2245 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2246 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2247 getpid (), fd, fd, func_str, buf, n, flags,
2250 size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
2257 int errno_val = errno;
2259 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2260 "rv %d, errno = %d", getpid (), fd, fd,
2261 func_str, size, errno_val);
2265 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2266 getpid (), fd, fd, size, size);
2272 sendmsg (int fd, const struct msghdr * message, int flags)
2275 const char *func_str;
2276 u32 sid = ldp_sid_from_fd (fd);
2278 if ((errno = -ldp_init ()))
2281 if (sid != INVALID_SESSION_ID)
2283 func_str = __func__;
2285 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2291 func_str = "libc_sendmsg";
2294 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2295 "message %p, flags 0x%x",
2296 getpid (), fd, fd, func_str, message, flags);
2298 size = libc_sendmsg (fd, message, flags);
2305 int errno_val = errno;
2307 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2308 "rv %d, errno = %d", getpid (), fd, fd,
2309 func_str, size, errno_val);
2313 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2314 getpid (), fd, fd, size, size);
2321 sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
2324 const char *func_str;
2325 u32 sid = ldp_sid_from_fd (fd);
2327 if ((errno = -ldp_init ()))
2330 if (sid != INVALID_SESSION_ID)
2332 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2338 func_str = "libc_sendmmsg";
2341 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2342 "vmessages %p, vlen %u, flags 0x%x",
2343 getpid (), fd, fd, func_str, vmessages, vlen, flags);
2345 size = libc_sendmmsg (fd, vmessages, vlen, flags);
2352 int errno_val = errno;
2354 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2355 "rv %d, errno = %d", getpid (), fd, fd,
2356 func_str, size, errno_val);
2360 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2361 getpid (), fd, fd, size, size);
2368 recvmsg (int fd, struct msghdr * message, int flags)
2371 const char *func_str;
2372 u32 sid = ldp_sid_from_fd (fd);
2374 if ((errno = -ldp_init ()))
2377 if (sid != INVALID_SESSION_ID)
2379 func_str = __func__;
2381 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2387 func_str = "libc_recvmsg";
2390 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2391 "message %p, flags 0x%x",
2392 getpid (), fd, fd, func_str, message, flags);
2394 size = libc_recvmsg (fd, message, flags);
2401 int errno_val = errno;
2403 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2404 "rv %d, errno = %d", getpid (), fd, fd,
2405 func_str, size, errno_val);
2409 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2410 getpid (), fd, fd, size, size);
2417 recvmmsg (int fd, struct mmsghdr *vmessages,
2418 unsigned int vlen, int flags, struct timespec *tmo)
2421 const char *func_str;
2422 u32 sid = ldp_sid_from_fd (fd);
2424 if ((errno = -ldp_init ()))
2427 if (sid != INVALID_SESSION_ID)
2429 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2435 func_str = "libc_recvmmsg";
2438 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2439 "vmessages %p, vlen %u, flags 0x%x, tmo %p",
2440 getpid (), fd, fd, func_str, vmessages, vlen,
2443 size = libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
2450 int errno_val = errno;
2452 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2453 "rv %d, errno = %d", getpid (), fd, fd,
2454 func_str, size, errno_val);
2458 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2459 getpid (), fd, fd, size, size);
2466 getsockopt (int fd, int level, int optname,
2467 void *__restrict optval, socklen_t * __restrict optlen)
2470 const char *func_str = __func__;
2471 u32 sid = ldp_sid_from_fd (fd);
2472 u32 buflen = optlen ? (u32) * optlen : 0;
2474 if ((errno = -ldp_init ()))
2477 if (sid != INVALID_SESSION_ID)
2487 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_NODELAY]";
2489 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2491 getpid (), fd, fd, func_str, sid, sid);
2492 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_NODELAY,
2496 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_USER_MSS]";
2498 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2500 getpid (), fd, fd, func_str, sid, sid);
2501 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_USER_MSS,
2505 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPIDLE]";
2507 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2509 getpid (), fd, fd, func_str, sid, sid);
2510 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
2514 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPINTVL]";
2516 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2517 "sid %u (0x%x), SOL_TCP",
2518 getpid (), fd, fd, func_str, sid, sid);
2519 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
2523 if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
2526 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x), "
2527 "SOL_TCP, TCP_INFO, optval %p, "
2528 "optlen %d: #LDP-NOP#",
2529 getpid (), fd, fd, sid, sid,
2531 memset (optval, 0, *optlen);
2539 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2540 "sid %u (0x%x), SOL_TCP, "
2541 "optname %d unsupported!",
2542 getpid (), fd, fd, func_str, sid, sid, optname);
2550 func_str = "vppcom_session_attr[SOL_IPV6,GET_V6ONLY]";
2552 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2554 getpid (), fd, fd, func_str, sid, sid);
2555 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_V6ONLY,
2560 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2561 "sid %u (0x%x), SOL_IPV6, "
2562 "optname %d unsupported!",
2563 getpid (), fd, fd, func_str, sid, sid, optname);
2571 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ACCEPTCONN]";
2573 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2575 getpid (), fd, fd, func_str, sid, sid);
2576 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LISTEN,
2580 func_str = "vppcom_session_attr[SOL_SOCKET,GET_KEEPALIVE]";
2582 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2584 getpid (), fd, fd, func_str, sid, sid);
2585 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_KEEPALIVE,
2589 func_str = "vppcom_session_attr[SOL_SOCKET,GET_PROTOCOL]";
2591 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2593 getpid (), fd, fd, func_str, sid, sid);
2594 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PROTOCOL,
2596 *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
2599 func_str = "vppcom_session_attr[SOL_SOCKET,GET_TX_FIFO_LEN]";
2601 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2602 "sid %u (0x%x), optlen %d",
2603 getpid (), fd, fd, func_str, sid, sid, buflen);
2604 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TX_FIFO_LEN,
2608 func_str = "vppcom_session_attr[SOL_SOCKET,GET_RX_FIFO_LEN]";
2610 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2611 "sid %u (0x%x), optlen %d",
2612 getpid (), fd, fd, func_str, sid, sid, buflen);
2613 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_RX_FIFO_LEN,
2617 func_str = "vppcom_session_attr[SOL_SOCKET,GET_REUSEADDR]";
2619 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2621 getpid (), fd, fd, func_str, sid, sid);
2622 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REUSEADDR,
2626 func_str = "vppcom_session_attr[SOL_SOCKET,GET_BROADCAST]";
2628 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2630 getpid (), fd, fd, func_str, sid, sid);
2631 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_BROADCAST,
2635 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ERROR]";
2637 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2639 getpid (), fd, fd, func_str, sid, sid);
2640 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_ERROR,
2645 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2646 "sid %u (0x%x), SOL_SOCKET, "
2647 "optname %d unsupported!",
2648 getpid (), fd, fd, func_str, sid, sid, optname);
2656 if (rv != VPPCOM_OK)
2664 func_str = "libc_getsockopt";
2667 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2668 "optname %d, optval %p, optlen %d",
2669 getpid (), fd, fd, func_str, level, optname,
2672 rv = libc_getsockopt (fd, level, optname, optval, optlen);
2679 int errno_val = errno;
2681 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2682 "rv %d, errno = %d", getpid (), fd, fd,
2683 func_str, rv, errno_val);
2687 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2688 getpid (), fd, fd, rv, rv);
2694 setsockopt (int fd, int level, int optname,
2695 const void *optval, socklen_t optlen)
2698 const char *func_str = __func__;
2699 u32 sid = ldp_sid_from_fd (fd);
2701 if ((errno = -ldp_init ()))
2704 if (sid != INVALID_SESSION_ID)
2714 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_NODELAY]";
2716 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2718 getpid (), fd, fd, func_str, sid, sid);
2719 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_NODELAY,
2720 (void *) optval, &optlen);
2723 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_USER_MSS]";
2725 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2727 getpid (), fd, fd, func_str, sid, sid);
2728 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_USER_MSS,
2729 (void *) optval, &optlen);
2732 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPIDLE]";
2734 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2736 getpid (), fd, fd, func_str, sid, sid);
2737 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
2738 (void *) optval, &optlen);
2741 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPINTVL]";
2743 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2744 "sid %u (0x%x), SOL_TCP",
2745 getpid (), fd, fd, func_str, sid, sid);
2746 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
2747 (void *) optval, &optlen);
2751 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2752 "sid %u (0x%x), SOL_TCP, "
2753 "optname %d unsupported!",
2754 getpid (), fd, fd, func_str, sid, sid, optname);
2762 func_str = "vppcom_session_attr[SOL_IPV6,SET_V6ONLY]";
2764 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2766 getpid (), fd, fd, func_str, sid, sid);
2767 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_V6ONLY,
2768 (void *) optval, &optlen);
2772 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2773 "sid %u (0x%x), SOL_IPV6, "
2774 "optname %d unsupported!",
2775 getpid (), fd, fd, func_str, sid, sid, optname);
2783 func_str = "vppcom_session_attr[SOL_SOCKET,SET_KEEPALIVE]";
2785 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2787 getpid (), fd, fd, func_str, sid, sid);
2788 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_KEEPALIVE,
2789 (void *) optval, &optlen);
2792 func_str = "vppcom_session_attr[SOL_SOCKET,SET_REUSEADDR]";
2794 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2796 getpid (), fd, fd, func_str, sid, sid);
2797 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_REUSEADDR,
2798 (void *) optval, &optlen);
2801 func_str = "vppcom_session_attr[SOL_SOCKET,SET_BROADCAST]";
2803 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2805 getpid (), fd, fd, func_str, sid, sid);
2806 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_BROADCAST,
2807 (void *) optval, &optlen);
2811 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2812 "sid %u (0x%x), SOL_SOCKET, "
2813 "optname %d unsupported!",
2814 getpid (), fd, fd, func_str, sid, sid, optname);
2822 if (rv != VPPCOM_OK)
2830 func_str = "libc_setsockopt";
2833 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2834 "optname %d, optval %p, optlen %d",
2835 getpid (), fd, fd, func_str, level, optname,
2838 rv = libc_setsockopt (fd, level, optname, optval, optlen);
2845 int errno_val = errno;
2847 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2848 "rv %d, errno = %d", getpid (), fd, fd,
2849 func_str, rv, errno_val);
2853 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2854 getpid (), fd, fd, rv, rv);
2860 listen (int fd, int n)
2863 const char *func_str;
2864 u32 sid = ldp_sid_from_fd (fd);
2866 if ((errno = -ldp_init ()))
2869 if (sid != INVALID_SESSION_ID)
2871 func_str = "vppcom_session_listen";
2873 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), n %d",
2874 getpid (), fd, fd, func_str, sid, sid, n);
2876 rv = vppcom_session_listen (sid, n);
2877 if (rv != VPPCOM_OK)
2885 func_str = "libc_listen";
2887 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): n %d", getpid (), fd,
2890 rv = libc_listen (fd, n);
2897 int errno_val = errno;
2899 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2900 "rv %d, errno = %d", getpid (), fd, fd,
2901 func_str, rv, errno_val);
2905 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2906 getpid (), fd, fd, rv, rv);
2912 ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
2913 socklen_t * __restrict addr_len, int flags)
2916 const char *func_str;
2917 u32 listen_sid = ldp_sid_from_fd (listen_fd);
2920 if ((errno = -ldp_init ()))
2923 if (listen_sid != INVALID_SESSION_ID)
2926 u8 src_addr[sizeof (struct sockaddr_in6)];
2927 memset (&ep, 0, sizeof (ep));
2930 func_str = "vppcom_session_accept";
2933 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2934 "listen sid %u (0x%x), ep %p, flags 0x%x",
2935 getpid (), listen_fd, listen_fd, func_str,
2936 listen_sid, listen_sid, ep, flags);
2938 accept_sid = vppcom_session_accept (listen_sid, &ep, flags);
2941 errno = -accept_sid;
2946 rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
2947 if (rv != VPPCOM_OK)
2949 (void) vppcom_session_close ((u32) accept_sid);
2955 func_str = "ldp_fd_from_sid";
2957 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2958 "accept sid %u (0x%x), ep %p, flags 0x%x",
2959 getpid (), listen_fd, listen_fd,
2960 func_str, accept_sid, accept_sid, ep, flags);
2961 rv = ldp_fd_alloc ((u32) accept_sid);
2964 (void) vppcom_session_close ((u32) accept_sid);
2973 func_str = "libc_accept4";
2976 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2977 "addr %p, addr_len %p, flags 0x%x",
2978 getpid (), listen_fd, listen_fd, func_str,
2979 addr, addr_len, flags);
2981 rv = libc_accept4 (listen_fd, addr, addr_len, flags);
2988 int errno_val = errno;
2990 clib_warning ("LDP<%d>: ERROR: listen fd %d (0x%x): %s() failed! "
2991 "rv %d, errno = %d", getpid (), listen_fd,
2992 listen_fd, func_str, rv, errno_val);
2996 clib_warning ("LDP<%d>: listen fd %d (0x%x): returning %d (0x%x)",
2997 getpid (), listen_fd, listen_fd, rv, rv);
3003 accept4 (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len,
3006 return ldp_accept4 (fd, addr, addr_len, flags);
3010 accept (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
3012 return ldp_accept4 (fd, addr, addr_len, 0);
3016 shutdown (int fd, int how)
3019 const char *func_str;
3020 u32 sid = ldp_sid_from_fd (fd);
3022 if ((errno = -ldp_init ()))
3025 if (sid != INVALID_SESSION_ID)
3027 func_str = "vppcom_session_close[TODO]";
3032 func_str = "libc_shutdown";
3035 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): how %d",
3036 getpid (), fd, fd, func_str, how);
3038 rv = libc_shutdown (fd, how);
3045 int errno_val = errno;
3047 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
3048 "rv %d, errno = %d", getpid (), fd, fd,
3049 func_str, rv, errno_val);
3053 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
3054 getpid (), fd, fd, rv, rv);
3060 epoll_create1 (int flags)
3062 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
3063 const char *func_str;
3066 if ((errno = -ldp_init ()))
3069 if (ldp->vcl_needs_real_epoll)
3071 rv = libc_epoll_create1 (flags);
3072 ldp->vcl_needs_real_epoll = 0;
3073 ldpw->vcl_mq_epfd = rv;
3074 LDBG (0, "LDP<%d>: created vcl epfd %u", getpid (), rv);
3077 func_str = "vppcom_epoll_create";
3079 LDBG (1, "LDP<%d>: calling %s()", getpid (), func_str);
3081 rv = vppcom_epoll_create ();
3083 if (PREDICT_FALSE (rv < 0))
3089 rv = ldp_fd_alloc ((u32) rv);
3095 int errno_val = errno;
3097 clib_warning ("LDP<%d>: ERROR: %s() failed! "
3098 "rv %d, errno = %d",
3099 getpid (), func_str, rv, errno_val);
3103 clib_warning ("LDP<%d>: returning epfd %d (0x%x)", getpid (), rv, rv);
3109 epoll_create (int size)
3111 return epoll_create1 (0);
3115 epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
3117 u32 vep_idx = ldp_sid_from_fd (epfd), sid;
3118 const char *func_str;
3121 if ((errno = -ldp_init ()))
3124 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
3126 /* The LDP epoll_create1 always creates VCL epfd's.
3127 * The app should never have a kernel base epoll fd unless it
3128 * was acquired outside of the LD_PRELOAD process context.
3129 * In any case, if we get one, punt it to libc_epoll_ctl.
3131 func_str = "libc_epoll_ctl";
3133 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): op %d, fd %d (0x%x),"
3134 " event %p", getpid (), epfd, epfd, func_str, op, fd, fd, event);
3136 rv = libc_epoll_ctl (epfd, op, fd, event);
3140 sid = ldp_sid_from_fd (fd);
3142 LDBG (0, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x), sid %d (0x%x)",
3143 getpid (), epfd, epfd, vep_idx, vep_idx, sid, sid);
3145 if (sid != INVALID_SESSION_ID)
3147 func_str = "vppcom_epoll_ctl";
3149 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3150 " op %d, sid %u (0x%x), event %p", getpid (), epfd, epfd,
3151 func_str, vep_idx, vep_idx, sid, sid, event);
3153 rv = vppcom_epoll_ctl (vep_idx, op, sid, event);
3154 if (rv != VPPCOM_OK)
3163 u32 size = sizeof (epfd);
3165 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
3166 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0,
3168 LDBG (1, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): %s() "
3169 "returned libc_epfd %d (0x%x)", getpid (), epfd, epfd,
3170 vep_idx, vep_idx, func_str, libc_epfd, libc_epfd);
3174 func_str = "libc_epoll_create1";
3176 LDBG (1, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): "
3177 "calling %s(): EPOLL_CLOEXEC", getpid (), epfd, epfd,
3178 vep_idx, vep_idx, func_str);
3180 libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
3187 func_str = "vppcom_session_attr[SET_LIBC_EPFD]";
3188 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3189 " VPPCOM_ATTR_SET_LIBC_EPFD, libc_epfd %d (0x%x), size %d",
3190 getpid (), epfd, epfd, func_str, vep_idx, vep_idx, libc_epfd,
3193 rv = vppcom_session_attr (vep_idx, VPPCOM_ATTR_SET_LIBC_EPFD,
3202 else if (PREDICT_FALSE (libc_epfd < 0))
3209 func_str = "libc_epoll_ctl";
3211 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): libc_epfd %d (0x%x), "
3212 "op %d, fd %d (0x%x), event %p", getpid (), epfd, epfd, func_str,
3213 libc_epfd, libc_epfd, op, fd, fd, event);
3215 rv = libc_epoll_ctl (libc_epfd, op, fd, event);
3223 int errno_val = errno;
3225 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
3226 "rv %d, errno = %d", getpid (), fd, fd,
3227 func_str, rv, errno_val);
3231 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
3232 getpid (), fd, fd, rv, rv);
3238 ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
3239 int timeout, const sigset_t * sigmask)
3241 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
3242 double time_to_wait = (double) 0, time_out, now = 0;
3243 u32 vep_idx = ldp_sid_from_fd (epfd);
3244 int libc_epfd, rv = 0;
3245 const char *func_str;
3247 if ((errno = -ldp_init ()))
3250 if (PREDICT_FALSE (!events || (timeout < -1)))
3256 if (epfd == ldpw->vcl_mq_epfd)
3257 return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
3259 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
3261 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): bad vep_idx %d (0x%x)!",
3262 getpid (), epfd, epfd, vep_idx, vep_idx);
3267 time_to_wait = ((timeout >= 0) ? (double) timeout : 0);
3268 time_out = clib_time_now (&ldpw->clib_time) + time_to_wait;
3270 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
3271 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
3272 if (PREDICT_FALSE (libc_epfd < 0))
3279 LDBG (2, "LDP<%d>: epfd %d (0x%x): vep_idx %d (0x%x), libc_epfd %d (0x%x), "
3280 "events %p, maxevents %d, timeout %d, sigmask %p: time_to_wait %.02f",
3281 getpid (), epfd, epfd, vep_idx, vep_idx, libc_epfd, libc_epfd, events,
3282 maxevents, timeout, sigmask, time_to_wait, time_out);
3285 if (!ldpw->epoll_wait_vcl)
3287 func_str = "vppcom_epoll_wait";
3289 LDBG (3, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3290 " events %p, maxevents %d", getpid (), epfd, epfd, func_str,
3291 vep_idx, vep_idx, events, maxevents);
3293 rv = vppcom_epoll_wait (vep_idx, events, maxevents, 0);
3296 ldpw->epoll_wait_vcl = 1;
3307 ldpw->epoll_wait_vcl = 0;
3311 func_str = "libc_epoll_pwait";
3313 LDBG (3, "LDP<%d>: epfd %d (0x%x): calling %s(): libc_epfd %d "
3314 "(0x%x), events %p, maxevents %d, sigmask %p", getpid (),
3315 epfd, epfd, func_str, libc_epfd, libc_epfd, events,
3316 maxevents, sigmask);
3318 rv = libc_epoll_pwait (libc_epfd, events, maxevents, 1, sigmask);
3324 now = clib_time_now (&ldpw->clib_time);
3326 while (now < time_out);
3335 int errno_val = errno;
3337 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): %s() failed! "
3338 "rv %d, errno = %d", getpid (), epfd, epfd,
3339 func_str, rv, errno_val);
3343 clib_warning ("LDP<%d>: epfd %d (0x%x): returning %d (0x%x)",
3344 getpid (), epfd, epfd, rv, rv);
3350 epoll_pwait (int epfd, struct epoll_event *events,
3351 int maxevents, int timeout, const sigset_t * sigmask)
3353 return ldp_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
3357 epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
3359 return ldp_epoll_pwait (epfd, events, maxevents, timeout, NULL);
3363 poll (struct pollfd *fds, nfds_t nfds, int timeout)
3365 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
3366 const char *func_str = __func__;
3367 int rv, i, n_revents = 0;
3370 double wait_for_time;
3372 LDBG (3, "LDP<%d>: fds %p, nfds %d, timeout %d", getpid (), fds, nfds,
3376 wait_for_time = (f64) timeout / 1000;
3380 for (i = 0; i < nfds; i++)
3385 LDBG (3, "LDP<%d>: fds[%d] fd %d (0x%0x) events = 0x%x revents = 0x%x",
3386 getpid (), i, fds[i].fd, fds[i].fd, fds[i].events,
3389 sid = ldp_sid_from_fd (fds[i].fd);
3390 if (sid != INVALID_SESSION_ID)
3392 fds[i].fd = -fds[i].fd;
3393 vec_add2 (ldpw->vcl_poll, vp, 1);
3396 vp->events = fds[i].events;
3397 #ifdef __USE_XOPEN2K
3398 if (fds[i].events & POLLRDNORM)
3399 vp->events |= POLLIN;
3400 if (fds[i].events & POLLWRNORM)
3401 vp->events |= POLLOUT;
3403 vp->revents = fds[i].revents;
3407 vec_add1 (ldpw->libc_poll, fds[i]);
3408 vec_add1 (ldpw->libc_poll_idxs, i);
3414 if (vec_len (ldpw->vcl_poll))
3416 func_str = "vppcom_poll";
3418 LDBG (3, "LDP<%d>: calling %s(): vcl_poll %p, n_sids %u (0x%x): "
3419 "n_libc_fds %u", getpid (), func_str, ldpw->vcl_poll,
3420 vec_len (ldpw->vcl_poll), vec_len (ldpw->vcl_poll),
3421 vec_len (ldpw->libc_poll));
3423 rv = vppcom_poll (ldpw->vcl_poll, vec_len (ldpw->vcl_poll), 0);
3434 if (vec_len (ldpw->libc_poll))
3436 func_str = "libc_poll";
3438 LDBG (3, "LDP<%d>: calling %s(): fds %p, nfds %u: n_sids %u",
3439 getpid (), fds, nfds, vec_len (ldpw->vcl_poll));
3441 rv = libc_poll (ldpw->libc_poll, vec_len (ldpw->libc_poll), 0);
3454 while ((wait_for_time == -1) ||
3455 (clib_time_now (&ldpw->clib_time) < wait_for_time));
3459 vec_foreach (vp, ldpw->vcl_poll)
3461 fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd;
3462 fds[vp->fds_ndx].revents = vp->revents;
3463 #ifdef __USE_XOPEN2K
3464 if ((fds[vp->fds_ndx].revents & POLLIN) &&
3465 (fds[vp->fds_ndx].events & POLLRDNORM))
3466 fds[vp->fds_ndx].revents |= POLLRDNORM;
3467 if ((fds[vp->fds_ndx].revents & POLLOUT) &&
3468 (fds[vp->fds_ndx].events & POLLWRNORM))
3469 fds[vp->fds_ndx].revents |= POLLWRNORM;
3472 vec_reset_length (ldpw->vcl_poll);
3474 for (i = 0; i < vec_len (ldpw->libc_poll); i++)
3476 fds[ldpw->libc_poll_idxs[i]].revents = ldpw->libc_poll[i].revents;
3478 vec_reset_length (ldpw->libc_poll_idxs);
3479 vec_reset_length (ldpw->libc_poll);
3485 int errno_val = errno;
3487 clib_warning ("LDP<%d>: ERROR: %s() failed! "
3488 "rv %d, errno = %d", getpid (),
3489 func_str, rv, errno_val);
3494 clib_warning ("LDP<%d>: returning %d (0x%x): n_sids %u, "
3495 "n_libc_fds %d", getpid (), rv, rv,
3496 vec_len (ldpw->vcl_poll), vec_len (ldpw->libc_poll));
3498 for (i = 0; i < nfds; i++)
3503 clib_warning ("LDP<%d>: fds[%d].fd %d (0x%0x), "
3504 ".events = 0x%x, .revents = 0x%x",
3505 getpid (), i, fds[i].fd, fds[i].fd,
3506 fds[i].events, fds[i].revents);
3517 ppoll (struct pollfd *fds, nfds_t nfds,
3518 const struct timespec *timeout, const sigset_t * sigmask)
3520 if ((errno = -ldp_init ()))
3523 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
3531 void CONSTRUCTOR_ATTRIBUTE ldp_constructor (void);
3533 void DESTRUCTOR_ATTRIBUTE ldp_destructor (void);
3536 * This function is called when the library is loaded
3539 ldp_constructor (void)
3541 swrap_constructor ();
3542 if (ldp_init () != 0)
3543 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
3545 else if (LDP_DEBUG > 0)
3546 clib_warning ("LDP<%d>: LDP constructor: done!\n", getpid ());
3550 * This function is called when the library is unloaded
3553 ldp_destructor (void)
3555 swrap_destructor ();
3558 vppcom_app_destroy ();
3562 /* Don't use clib_warning() here because that calls writev()
3563 * which will call ldp_init().
3566 printf ("%s:%d: LDP<%d>: LDP destructor: done!\n",
3567 __func__, __LINE__, getpid ());
3572 * fd.io coding-style-patch-verification: ON
3575 * eval: (c-set-style "gnu")