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 ("ldp<%d>: " _fmt, getpid(), ##_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, "\nERROR: ldp_init: vppcom_app_create()"
265 " failed! rv = %d (%s)\n", rv, vppcom_retval_str (rv));
269 ldp->vcl_needs_real_epoll = 0;
270 pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
271 ldpw = ldp_worker_get_current ();
273 char *env_var_str = getenv (LDP_ENV_DEBUG);
277 if (sscanf (env_var_str, "%u", &tmp) != 1)
278 clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level specified in"
279 " the env var " LDP_ENV_DEBUG " (%s)!", getpid (),
284 LDBG (0, "configured LDP debug level (%u) from env var "
285 LDP_ENV_DEBUG "!", ldp->debug);
289 env_var_str = getenv (LDP_ENV_APP_NAME);
292 ldp_set_app_name (env_var_str);
293 LDBG (0, "configured LDP app name (%s) from the env var "
294 LDP_ENV_APP_NAME "!", ldp->app_name);
297 env_var_str = getenv (LDP_ENV_SID_BIT);
301 if (sscanf (env_var_str, "%u", &sb) != 1)
303 clib_warning ("LDP<%d>: WARNING: Invalid LDP sid bit specified in"
304 " the env var " LDP_ENV_SID_BIT " (%s)! sid bit "
305 "value %d (0x%x)", getpid (), env_var_str,
306 ldp->sid_bit_val, ldp->sid_bit_val);
308 else if (sb < LDP_SID_BIT_MIN)
310 ldp->sid_bit_val = (1 << LDP_SID_BIT_MIN);
311 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
313 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
314 " env var " LDP_ENV_SID_BIT " (%s) is too small. "
315 "Using LDP_SID_BIT_MIN (%d)! sid bit value %d (0x%x)",
316 getpid (), sb, env_var_str, LDP_SID_BIT_MIN,
317 ldp->sid_bit_val, ldp->sid_bit_val);
319 else if (sb > LDP_SID_BIT_MAX)
321 ldp->sid_bit_val = (1 << LDP_SID_BIT_MAX);
322 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
324 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
325 " env var " LDP_ENV_SID_BIT " (%s) is too big. Using"
326 " LDP_SID_BIT_MAX (%d)! sid bit value %d (0x%x)",
327 getpid (), sb, env_var_str, LDP_SID_BIT_MAX,
328 ldp->sid_bit_val, ldp->sid_bit_val);
332 ldp->sid_bit_val = (1 << sb);
333 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
335 LDBG (0, "configured LDP sid bit (%u) from "
336 LDP_ENV_SID_BIT "! sid bit value %d (0x%x)", sb,
337 ldp->sid_bit_val, ldp->sid_bit_val);
341 clib_time_init (&ldpw->clib_time);
342 clib_rwlock_init (&ldp->fd_table_lock);
343 LDBG (0, "LDP initialization: done!");
352 u32 sid = ldp_sid_from_fd (fd);
354 if ((errno = -ldp_init ()))
357 if (sid != INVALID_SESSION_ID)
361 epfd = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
364 LDBG (0, "fd %d (0x%x): calling libc_close: epfd %u (0x%x)",
367 rv = libc_close (epfd);
370 u32 size = sizeof (epfd);
373 (void) vppcom_session_attr (sid, VPPCOM_ATTR_SET_LIBC_EPFD,
377 else if (PREDICT_FALSE (epfd < 0))
384 LDBG (0, "fd %d (0x%x): calling vppcom_session_close: sid %u (0x%x)",
387 refcnt = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REFCNT, 0, 0);
388 rv = vppcom_session_close (sid);
395 ldp_fd_free_w_sid (sid);
399 LDBG (0, "fd %d (0x%x): calling libc_close", fd, fd);
400 rv = libc_close (fd);
405 LDBG (1, "fd %d (0x%x): returning %d (0x%x)", fd, fd, rv, rv);
410 read (int fd, void *buf, size_t nbytes)
413 u32 sid = ldp_sid_from_fd (fd);
415 if ((errno = -ldp_init ()))
418 if (sid != INVALID_SESSION_ID)
420 LDBG (2, "fd %d (0x%x): calling vppcom_session_read(): sid %u (0x%x),"
421 " buf %p, nbytes %u", fd, fd, sid, sid, buf, nbytes);
423 size = vppcom_session_read (sid, buf, nbytes);
432 LDBG (2, "fd %d (0x%x): calling libc_read(): buf %p, nbytes %u",
433 fd, fd, buf, nbytes);
435 size = libc_read (fd, buf, nbytes);
438 LDBG (2, "fd %d (0x%x): returning %d (0x%x)", fd, fd, size, size);
443 readv (int fd, const struct iovec * iov, int iovcnt)
446 u32 sid = ldp_sid_from_fd (fd);
447 int rv = 0, i, total = 0;
449 if ((errno = -ldp_init ()))
452 if (sid != INVALID_SESSION_ID)
456 for (i = 0; i < iovcnt; ++i)
458 LDBG (2, "fd %d (0x%x): calling vppcom_session_read() [%d]:"
459 " sid %u (0x%x), iov %p, iovcnt %d, total %d", fd, fd, i,
460 sid, sid, iov, iovcnt, total);
462 rv = vppcom_session_read (sid, iov[i].iov_base, iov[i].iov_len);
468 if (rv < iov[i].iov_len)
470 LDBG (2, "fd %d (0x%x): rv (%d) < iov[%d].iov_len (%d)",
471 fd, fd, rv, i, iov[i].iov_len);
477 while ((rv >= 0) && (total == 0));
489 LDBG (2, "fd %d (0x%x): calling libc_readv(): iov %p, iovcnt %d", fd,
492 size = libc_readv (fd, iov, iovcnt);
496 LDBG (2, "fd %d (0x%x): returning %d (0x%x)", fd, fd, size, size);
501 write (int fd, const void *buf, size_t nbytes)
504 u32 sid = ldp_sid_from_fd (fd);
506 if ((errno = -ldp_init ()))
509 if (sid != INVALID_SESSION_ID)
511 LDBG (2, "fd %d (0x%x): calling vppcom_session_write(): sid %u (0x%x), "
512 "buf %p, nbytes %u", fd, fd, sid, sid, buf, nbytes);
514 size = vppcom_session_write_msg (sid, (void *) buf, nbytes);
523 LDBG (2, "fd %d (0x%x): calling libc_write(): buf %p, nbytes %u",
524 fd, fd, buf, nbytes);
526 size = libc_write (fd, buf, nbytes);
529 LDBG (2, "fd %d (0x%x): returning %d (0x%x)", fd, fd, size, size);
534 writev (int fd, const struct iovec * iov, int iovcnt)
536 ssize_t size = 0, total = 0;
537 u32 sid = ldp_sid_from_fd (fd);
541 * Use [f]printf() instead of clib_warning() to prevent recursion SIGSEGV.
544 if ((errno = -ldp_init ()))
547 if (sid != INVALID_SESSION_ID)
551 for (i = 0; i < iovcnt; ++i)
553 rv = vppcom_session_write_msg (sid, iov[i].iov_base,
560 if (rv < iov[i].iov_len)
565 while ((rv >= 0) && (total == 0));
577 size = libc_writev (fd, iov, iovcnt);
584 fcntl (int fd, int cmd, ...)
586 const char *func_str = __func__;
589 u32 sid = ldp_sid_from_fd (fd);
591 if ((errno = -ldp_init ()))
595 if (sid != INVALID_SESSION_ID)
597 int flags = va_arg (ap, int);
600 size = sizeof (flags);
605 func_str = "vppcom_session_attr[SET_FLAGS]";
606 LDBG (2, "fd %d (0x%x): calling %s(): sid %u (0x%x) "
607 "flags %d (0x%x), size %d", fd, fd, func_str, sid,
608 sid, flags, flags, size);
610 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
615 func_str = "vppcom_session_attr[GET_FLAGS]";
616 LDBG (2, "fd %d (0x%x): calling %s(): sid %u (0x%x), "
617 "flags %d (0x%x), size %d", fd, fd, func_str, sid,
618 sid, flags, flags, size);
620 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
624 LDBG (2, "fd %d (0x%x), cmd %d (F_GETFL): %s() "
625 "returned flags %d (0x%x)", fd, fd, cmd,
626 func_str, flags, flags);
631 /* TODO handle this */
632 LDBG (0, "F_SETFD ignored flags %u", flags);
647 func_str = "libc_vfcntl";
649 LDBG (2, "fd %d (0x%x): calling %s(): cmd %d", fd, fd, func_str, cmd);
651 rv = libc_vfcntl (fd, cmd, ap);
660 int errno_val = errno;
662 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
663 "rv %d, errno = %d", getpid (), fd, fd,
664 func_str, rv, errno_val);
668 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
669 getpid (), fd, fd, rv, rv);
675 ioctl (int fd, unsigned long int cmd, ...)
677 const char *func_str;
680 u32 sid = ldp_sid_from_fd (fd);
682 if ((errno = -ldp_init ()))
686 if (sid != INVALID_SESSION_ID)
688 func_str = "vppcom_session_attr[GET_NREAD]";
695 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
696 getpid (), fd, fd, func_str, sid, sid);
698 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NREAD, 0, 0);
703 u32 flags = va_arg (ap, int) ? O_NONBLOCK : 0;
704 u32 size = sizeof (flags);
706 /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than
707 * non-blocking, the flags should be read here and merged
711 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
712 "sid %u (0x%x), flags %d (0x%x), size %d",
713 getpid (), fd, fd, func_str, sid, sid,
716 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
733 func_str = "libc_vioctl";
736 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
737 getpid (), fd, fd, func_str, cmd);
739 rv = libc_vioctl (fd, cmd, ap);
746 int errno_val = errno;
748 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
749 "rv %d, errno = %d", getpid (), fd, fd,
750 func_str, rv, errno_val);
754 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
755 getpid (), fd, fd, rv, rv);
762 ldp_pselect (int nfds, fd_set * __restrict readfds,
763 fd_set * __restrict writefds,
764 fd_set * __restrict exceptfds,
765 const struct timespec *__restrict timeout,
766 const __sigset_t * __restrict sigmask)
768 uword sid_bits, sid_bits_set, libc_bits, libc_bits_set;
769 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
770 u32 minbits = clib_max (nfds, BITS (uword)), sid;
771 char *func_str = "##";
783 time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
784 (f64) 0 : (f64) timeout->tv_sec +
785 (f64) timeout->tv_nsec / (f64) 1000000000;
787 /* select as fine grained sleep */
790 LDBG (3, "sleeping for %.02f seconds", time_out);
792 time_out += clib_time_now (&ldpw->clib_time);
793 while (clib_time_now (&ldpw->clib_time) < time_out)
807 if (nfds <= ldp->sid_bit_val)
809 func_str = "libc_pselect";
811 LDBG (3, "calling %s(): nfds %d, readfds %p, writefds %p, "
812 "exceptfds %p, timeout %p, sigmask %p", func_str, nfds,
813 readfds, writefds, exceptfds, timeout, sigmask);
815 rv = libc_pselect (nfds, readfds, writefds, exceptfds,
820 if (PREDICT_FALSE (ldp->sid_bit_val > FD_SETSIZE / 2))
822 clib_warning ("LDP<%d>: ERROR: LDP sid bit value %d (0x%x) > "
823 "FD_SETSIZE/2 %d (0x%x)!", getpid (),
824 ldp->sid_bit_val, ldp->sid_bit_val,
825 FD_SETSIZE / 2, FD_SETSIZE / 2);
830 sid_bits = libc_bits = 0;
831 u32 n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0);
834 clib_bitmap_validate (ldpw->sid_rd_bitmap, minbits);
835 clib_bitmap_validate (ldpw->libc_rd_bitmap, minbits);
836 clib_bitmap_validate (ldpw->rd_bitmap, minbits);
837 clib_memcpy_fast (ldpw->rd_bitmap, readfds, n_bytes);
838 memset (readfds, 0, n_bytes);
841 clib_bitmap_foreach (fd, ldpw->rd_bitmap, ({
844 sid = ldp_sid_from_fd (fd);
845 LDBG (3, "readfds: fd %d (0x%x), sid %u (0x%x)", fd, fd, sid, sid);
846 if (sid == INVALID_SESSION_ID)
847 clib_bitmap_set_no_check (ldpw->libc_rd_bitmap, fd, 1);
849 clib_bitmap_set_no_check (ldpw->sid_rd_bitmap,
850 vppcom_session_index (sid), 1);
854 sid_bits_set = clib_bitmap_last_set (ldpw->sid_rd_bitmap) + 1;
855 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
857 libc_bits_set = clib_bitmap_last_set (ldpw->libc_rd_bitmap) + 1;
858 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
860 LDBG (3, "readfds: sid_bits_set %d, sid_bits %d, "
861 "libc_bits_set %d, libc_bits %d", sid_bits_set,
862 sid_bits, libc_bits_set, libc_bits);
866 clib_bitmap_validate (ldpw->sid_wr_bitmap, minbits);
867 clib_bitmap_validate (ldpw->libc_wr_bitmap, minbits);
868 clib_bitmap_validate (ldpw->wr_bitmap, minbits);
869 clib_memcpy_fast (ldpw->wr_bitmap, writefds, n_bytes);
870 memset (writefds, 0, n_bytes);
873 clib_bitmap_foreach (fd, ldpw->wr_bitmap, ({
876 sid = ldp_sid_from_fd (fd);
877 LDBG (3, "writefds: fd %d (0x%x), sid %u (0x%x)", fd, fd, sid, sid);
878 if (sid == INVALID_SESSION_ID)
879 clib_bitmap_set_no_check (ldpw->libc_wr_bitmap, fd, 1);
881 clib_bitmap_set_no_check (ldpw->sid_wr_bitmap,
882 vppcom_session_index (sid), 1);
886 sid_bits_set = clib_bitmap_last_set (ldpw->sid_wr_bitmap) + 1;
887 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
889 libc_bits_set = clib_bitmap_last_set (ldpw->libc_wr_bitmap) + 1;
890 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
892 LDBG (3, "writefds: sid_bits_set %d, sid_bits %d, "
893 "libc_bits_set %d, libc_bits %d",
894 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
898 clib_bitmap_validate (ldpw->sid_ex_bitmap, minbits);
899 clib_bitmap_validate (ldpw->libc_ex_bitmap, minbits);
900 clib_bitmap_validate (ldpw->ex_bitmap, minbits);
901 clib_memcpy_fast (ldpw->ex_bitmap, exceptfds, n_bytes);
902 memset (exceptfds, 0, n_bytes);
905 clib_bitmap_foreach (fd, ldpw->ex_bitmap, ({
908 sid = ldp_sid_from_fd (fd);
909 LDBG (3, "exceptfds: fd %d (0x%x), sid %u (0x%x)", fd, fd, sid, sid);
910 if (sid == INVALID_SESSION_ID)
911 clib_bitmap_set_no_check (ldpw->libc_ex_bitmap, fd, 1);
913 clib_bitmap_set_no_check (ldpw->sid_ex_bitmap,
914 vppcom_session_index (sid), 1);
918 sid_bits_set = clib_bitmap_last_set (ldpw->sid_ex_bitmap) + 1;
919 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
921 libc_bits_set = clib_bitmap_last_set (ldpw->libc_ex_bitmap) + 1;
922 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
924 LDBG (3, "exceptfds: sid_bits_set %d, sid_bits %d, "
925 "libc_bits_set %d, libc_bits %d",
926 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
929 if (PREDICT_FALSE (!sid_bits && !libc_bits))
940 if (!ldpw->select_vcl)
942 func_str = "vppcom_select";
945 clib_memcpy_fast (ldpw->rd_bitmap, ldpw->sid_rd_bitmap,
946 vec_len (ldpw->rd_bitmap) *
947 sizeof (clib_bitmap_t));
949 clib_memcpy_fast (ldpw->wr_bitmap, ldpw->sid_wr_bitmap,
950 vec_len (ldpw->wr_bitmap) *
951 sizeof (clib_bitmap_t));
953 clib_memcpy_fast (ldpw->ex_bitmap, ldpw->sid_ex_bitmap,
954 vec_len (ldpw->ex_bitmap) *
955 sizeof (clib_bitmap_t));
957 rv = vppcom_select (sid_bits,
958 readfds ? ldpw->rd_bitmap : NULL,
959 writefds ? ldpw->wr_bitmap : NULL,
960 exceptfds ? ldpw->ex_bitmap : NULL, 0);
971 clib_bitmap_foreach (sid, ldpw->rd_bitmap,
973 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
974 if (PREDICT_FALSE (fd < 0))
980 FD_SET (fd, readfds);
987 clib_bitmap_foreach (sid, ldpw->wr_bitmap,
989 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
990 if (PREDICT_FALSE (fd < 0))
996 FD_SET (fd, writefds);
1003 clib_bitmap_foreach (sid, ldpw->ex_bitmap,
1005 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
1006 if (PREDICT_FALSE (fd < 0))
1012 FD_SET (fd, exceptfds);
1016 ldpw->select_vcl = 1;
1021 ldpw->select_vcl = 0;
1025 struct timespec tspec;
1027 func_str = "libc_pselect";
1030 clib_memcpy_fast (readfds, ldpw->libc_rd_bitmap,
1031 vec_len (ldpw->rd_bitmap) *
1032 sizeof (clib_bitmap_t));
1034 clib_memcpy_fast (writefds, ldpw->libc_wr_bitmap,
1035 vec_len (ldpw->wr_bitmap) *
1036 sizeof (clib_bitmap_t));
1038 clib_memcpy_fast (exceptfds, ldpw->libc_ex_bitmap,
1039 vec_len (ldpw->ex_bitmap) *
1040 sizeof (clib_bitmap_t));
1041 tspec.tv_sec = tspec.tv_nsec = 0;
1042 rv = libc_pselect (libc_bits,
1043 readfds ? readfds : NULL,
1044 writefds ? writefds : NULL,
1045 exceptfds ? exceptfds : NULL, &tspec, sigmask);
1050 while ((time_out == -1) || (clib_time_now (&ldpw->clib_time) < time_out));
1054 /* TBD: set timeout to amount of time left */
1055 clib_bitmap_zero (ldpw->rd_bitmap);
1056 clib_bitmap_zero (ldpw->sid_rd_bitmap);
1057 clib_bitmap_zero (ldpw->libc_rd_bitmap);
1058 clib_bitmap_zero (ldpw->wr_bitmap);
1059 clib_bitmap_zero (ldpw->sid_wr_bitmap);
1060 clib_bitmap_zero (ldpw->libc_wr_bitmap);
1061 clib_bitmap_zero (ldpw->ex_bitmap);
1062 clib_bitmap_zero (ldpw->sid_ex_bitmap);
1063 clib_bitmap_zero (ldpw->libc_ex_bitmap);
1069 int errno_val = errno;
1071 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1072 "rv %d, errno = %d", getpid (),
1073 func_str, rv, errno_val);
1077 clib_warning ("LDP<%d>: returning %d (0x%x)", getpid (), rv, rv);
1083 select (int nfds, fd_set * __restrict readfds,
1084 fd_set * __restrict writefds,
1085 fd_set * __restrict exceptfds, struct timeval *__restrict timeout)
1087 struct timespec tspec;
1091 tspec.tv_sec = timeout->tv_sec;
1092 tspec.tv_nsec = timeout->tv_usec * 1000;
1094 return ldp_pselect (nfds, readfds, writefds, exceptfds,
1095 timeout ? &tspec : NULL, NULL);
1098 #ifdef __USE_XOPEN2K
1100 pselect (int nfds, fd_set * __restrict readfds,
1101 fd_set * __restrict writefds,
1102 fd_set * __restrict exceptfds,
1103 const struct timespec *__restrict timeout,
1104 const __sigset_t * __restrict sigmask)
1106 return ldp_pselect (nfds, readfds, writefds, exceptfds, timeout, 0);
1111 socket (int domain, int type, int protocol)
1113 const char *func_str;
1115 u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
1116 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1118 if ((errno = -ldp_init ()))
1121 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1122 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
1125 u8 proto = ((sock_type == SOCK_DGRAM) ?
1126 VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
1128 func_str = "vppcom_session_create";
1130 LDBG (0, "calling %s(): proto %u (%s), is_nonblocking %u",
1131 func_str, proto, vppcom_proto_str (proto), is_nonblocking);
1133 sid = vppcom_session_create (proto, is_nonblocking);
1141 func_str = "ldp_fd_from_sid";
1142 rv = ldp_fd_alloc (sid);
1145 (void) vppcom_session_close (sid);
1153 func_str = "libc_socket";
1155 LDBG (0, "calling %s()", func_str);
1157 rv = libc_socket (domain, type, protocol);
1164 int errno_val = errno;
1166 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1167 "rv %d, errno = %d",
1168 getpid (), func_str, rv, errno_val);
1172 clib_warning ("returning fd %d (0x%x)", getpid (), rv, rv);
1178 * Create two new sockets, of type TYPE in domain DOMAIN and using
1179 * protocol PROTOCOL, which are connected to each other, and put file
1180 * descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
1181 * one will be chosen automatically.
1182 * Returns 0 on success, -1 for errors.
1185 socketpair (int domain, int type, int protocol, int fds[2])
1187 const char *func_str;
1189 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1191 if ((errno = -ldp_init ()))
1194 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1195 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
1197 func_str = __func__;
1199 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1205 func_str = "libc_socket";
1207 LDBG (1, "calling %s()", func_str);
1209 rv = libc_socketpair (domain, type, protocol, fds);
1216 int errno_val = errno;
1218 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1219 "rv %d, errno = %d",
1220 getpid (), func_str, rv, errno_val);
1224 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1230 bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
1233 u32 sid = ldp_sid_from_fd (fd);
1235 if ((errno = -ldp_init ()))
1238 if (sid != INVALID_SESSION_ID)
1242 switch (addr->sa_family)
1245 if (len != sizeof (struct sockaddr_in))
1248 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1249 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1254 ep.is_ip4 = VPPCOM_IS_IP4;
1255 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1256 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1260 if (len != sizeof (struct sockaddr_in6))
1263 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1264 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1269 ep.is_ip4 = VPPCOM_IS_IP6;
1270 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1271 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
1275 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): "
1276 "Unsupported address family %u!",
1277 getpid (), fd, fd, sid, sid, addr->sa_family);
1278 errno = EAFNOSUPPORT;
1282 LDBG (0, "fd %d (0x%x): calling vppcom_session_bind(): "
1283 "sid %u (0x%x), addr %p, len %u", fd, fd, sid, sid, addr, len);
1285 rv = vppcom_session_bind (sid, &ep);
1286 if (rv != VPPCOM_OK)
1294 LDBG (0, "fd %d (0x%x): calling libc_bind(): addr %p, len %u",
1297 rv = libc_bind (fd, addr, len);
1301 LDBG (1, "fd %d (0x%x): returning %d", fd, fd, rv);
1307 ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
1308 vppcom_endpt_t * ep)
1311 int sa_len, copy_len;
1313 if ((errno = -ldp_init ()))
1316 if (addr && len && ep)
1318 addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6;
1319 switch (addr->sa_family)
1322 ((struct sockaddr_in *) addr)->sin_port = ep->port;
1323 if (*len > sizeof (struct sockaddr_in))
1324 *len = sizeof (struct sockaddr_in);
1325 sa_len = sizeof (struct sockaddr_in) - sizeof (struct in_addr);
1326 copy_len = *len - sa_len;
1328 memcpy (&((struct sockaddr_in *) addr)->sin_addr, ep->ip,
1333 ((struct sockaddr_in6 *) addr)->sin6_port = ep->port;
1334 if (*len > sizeof (struct sockaddr_in6))
1335 *len = sizeof (struct sockaddr_in6);
1336 sa_len = sizeof (struct sockaddr_in6) - sizeof (struct in6_addr);
1337 copy_len = *len - sa_len;
1339 memcpy (((struct sockaddr_in6 *) addr)->sin6_addr.
1340 __in6_u.__u6_addr8, ep->ip, copy_len);
1353 getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
1356 const char *func_str;
1357 u32 sid = ldp_sid_from_fd (fd);
1359 if ((errno = -ldp_init ()))
1362 if (sid != INVALID_SESSION_ID)
1365 u8 addr_buf[sizeof (struct in6_addr)];
1366 u32 size = sizeof (ep);
1369 func_str = "vppcom_session_attr[GET_LCL_ADDR]";
1372 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1374 getpid (), fd, fd, func_str, sid, sid, addr, len);
1376 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
1377 if (rv != VPPCOM_OK)
1384 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
1385 if (rv != VPPCOM_OK)
1394 func_str = "libc_getsockname";
1397 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1399 getpid (), fd, fd, func_str, addr, len);
1401 rv = libc_getsockname (fd, addr, len);
1408 int errno_val = errno;
1410 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1411 "rv %d, errno = %d", getpid (), fd, fd,
1412 func_str, rv, errno_val);
1416 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1417 getpid (), fd, fd, rv, rv);
1423 connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
1426 u32 sid = ldp_sid_from_fd (fd);
1428 if ((errno = -ldp_init ()))
1433 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): NULL addr, len %u",
1434 getpid (), fd, fd, len);
1440 if (sid != INVALID_SESSION_ID)
1444 switch (addr->sa_family)
1447 if (len != sizeof (struct sockaddr_in))
1450 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1451 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1456 ep.is_ip4 = VPPCOM_IS_IP4;
1457 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1458 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1462 if (len != sizeof (struct sockaddr_in6))
1465 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1466 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1471 ep.is_ip4 = VPPCOM_IS_IP6;
1472 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1473 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
1477 clib_warning ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): "
1478 "Unsupported address family %u!",
1479 getpid (), fd, fd, sid, sid, addr->sa_family);
1480 errno = EAFNOSUPPORT;
1484 LDBG (0, "fd %d (0x%x): calling vppcom_session_connect(): sid %u (0x%x)"
1485 " addr %p len %u", fd, fd, sid, sid, addr, len);
1487 rv = vppcom_session_connect (sid, &ep);
1488 if (rv != VPPCOM_OK)
1496 LDBG (0, "fd %d (0x%x): calling libc_connect(): addr %p, len %u",
1499 rv = libc_connect (fd, addr, len);
1503 LDBG (1, "fd %d (0x%x): returning %d (0x%x)", fd, fd, rv, rv);
1508 getpeername (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_PEER_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_PEER_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_getpeername";
1552 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1554 getpid (), fd, fd, func_str, addr, len);
1556 rv = libc_getpeername (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 send (int fd, const void *buf, size_t n, int flags)
1581 const char *func_str;
1582 u32 sid = ldp_sid_from_fd (fd);
1584 if ((errno = -ldp_init ()))
1587 if (sid != INVALID_SESSION_ID)
1590 func_str = "vppcom_session_sendto";
1593 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1594 "buf %p, n %u, flags 0x%x",
1595 getpid (), fd, fd, func_str, sid, sid, buf, n, flags);
1597 size = vppcom_session_sendto (sid, (void *) buf, n, flags, NULL);
1598 if (size < VPPCOM_OK)
1606 func_str = "libc_send";
1609 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1610 "buf %p, n %u, flags 0x%x",
1611 getpid (), fd, fd, func_str, buf, n, flags);
1613 size = libc_send (fd, buf, n, flags);
1620 int errno_val = errno;
1622 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1623 "rv %d, errno = %d", getpid (), fd, fd,
1624 func_str, size, errno_val);
1628 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1629 getpid (), fd, fd, size, size);
1635 sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
1637 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
1639 const char *func_str;
1640 u32 sid = ldp_sid_from_fd (out_fd);
1642 if ((errno = -ldp_init ()))
1645 if (sid != INVALID_SESSION_ID)
1648 ssize_t results = 0;
1649 size_t n_bytes_left = len;
1650 size_t bytes_to_read;
1654 u32 flags, flags_len = sizeof (flags);
1656 func_str = "vppcom_session_attr[GET_FLAGS]";
1657 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
1659 if (PREDICT_FALSE (rv != VPPCOM_OK))
1661 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1662 "sid %u (0x%x), returned %d (%s)!", getpid (),
1663 out_fd, out_fd, func_str, sid, sid, rv,
1664 vppcom_retval_str (rv));
1666 vec_reset_length (ldpw->io_buffer);
1674 off_t off = lseek (in_fd, *offset, SEEK_SET);
1675 if (PREDICT_FALSE (off == -1))
1679 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1680 "SEEK_SET failed: in_fd %d, offset %p, "
1681 "*offset %ld, rv %ld, errno %d", getpid (),
1682 out_fd, out_fd, in_fd, offset, *offset, off,
1689 ASSERT (off == *offset);
1694 func_str = "vppcom_session_attr[GET_NWRITE]";
1695 size = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NWRITE, 0, 0);
1699 ("LDP<%d>: ERROR: fd %d (0x%x): %s(): sid %u (0x%x), "
1700 "returned %d (%s)!", getpid (), out_fd, out_fd, func_str,
1701 sid, sid, size, vppcom_retval_str (size));
1702 vec_reset_length (ldpw->io_buffer);
1708 bytes_to_read = size;
1711 ("LDP<%d>: fd %d (0x%x): called %s(): sid %u (0x%x), "
1712 "results %ld, n_bytes_left %lu, bytes_to_read %lu", getpid (),
1713 out_fd, out_fd, func_str, sid, sid, results, n_bytes_left,
1716 if (bytes_to_read == 0)
1718 if (flags & O_NONBLOCK)
1723 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1725 getpid (), out_fd, out_fd, sid, sid);
1733 bytes_to_read = clib_min (n_bytes_left, bytes_to_read);
1734 vec_validate (ldpw->io_buffer, bytes_to_read);
1735 nbytes = libc_read (in_fd, ldpw->io_buffer, bytes_to_read);
1738 func_str = "libc_read";
1740 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): in_fd (%d), "
1741 "io_buffer %p, bytes_to_read %lu, rv %d, "
1742 "errno %d", getpid (), out_fd, out_fd, func_str,
1743 in_fd, ldpw->io_buffer, bytes_to_read, nbytes,
1749 vec_reset_length (ldpw->io_buffer);
1755 func_str = "vppcom_session_write";
1758 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1759 "buf %p, nbytes %u: results %d, n_bytes_left %d", getpid (),
1760 out_fd, out_fd, func_str, sid, sid, ldpw->io_buffer, nbytes,
1761 results, n_bytes_left);
1763 size = vppcom_session_write (sid, ldpw->io_buffer, nbytes);
1766 if (size == VPPCOM_EAGAIN)
1768 if (flags & O_NONBLOCK)
1774 ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1775 "EAGAIN", getpid (), out_fd, out_fd, sid, sid);
1785 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s():"
1786 "sid %u, io_buffer %p, nbytes %u "
1788 getpid (), out_fd, out_fd, func_str,
1789 sid, ldpw->io_buffer, nbytes,
1790 size, vppcom_retval_str (size));
1794 vec_reset_length (ldpw->io_buffer);
1803 ASSERT (n_bytes_left >= nbytes);
1804 n_bytes_left = n_bytes_left - nbytes;
1806 while (n_bytes_left > 0);
1809 vec_reset_length (ldpw->io_buffer);
1812 off_t off = lseek (in_fd, *offset, SEEK_SET);
1813 if (PREDICT_FALSE (off == -1))
1817 clib_warning ("LDP<%d>: ERROR: %s(): SEEK_SET failed: "
1818 "in_fd %d, offset %p, *offset %ld, "
1819 "rv %ld, errno %d", getpid (), in_fd,
1820 offset, *offset, off, errno_val);
1826 ASSERT (off == *offset);
1827 *offset += results + 1;
1839 func_str = "libc_send";
1842 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1843 "in_fd %d, offset %p, len %u",
1844 getpid (), out_fd, out_fd, func_str,
1845 in_fd, offset, len);
1847 size = libc_sendfile (out_fd, in_fd, offset, len);
1855 int errno_val = errno;
1857 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1858 "rv %d, errno = %d", getpid (), out_fd, out_fd,
1859 func_str, size, errno_val);
1863 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1864 getpid (), out_fd, out_fd, size, size);
1870 sendfile64 (int out_fd, int in_fd, off_t * offset, size_t len)
1872 return sendfile (out_fd, in_fd, offset, len);
1876 recv (int fd, void *buf, size_t n, int flags)
1879 const char *func_str;
1880 u32 sid = ldp_sid_from_fd (fd);
1882 if ((errno = -ldp_init ()))
1885 if (sid != INVALID_SESSION_ID)
1887 func_str = "vppcom_session_recvfrom";
1890 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1891 "sid %u (0x%x), buf %p, n %u, flags 0x%x", getpid (),
1892 fd, fd, func_str, sid, sid, buf, n, flags);
1894 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
1903 func_str = "libc_recv";
1906 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1907 "buf %p, n %u, flags 0x%x", getpid (),
1908 fd, fd, func_str, buf, n, flags);
1910 size = libc_recv (fd, buf, n, flags);
1917 int errno_val = errno;
1919 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1920 "rv %d, errno = %d", getpid (), fd, fd,
1921 func_str, size, errno_val);
1925 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1926 getpid (), fd, fd, size, size);
1932 sendto (int fd, const void *buf, size_t n, int flags,
1933 __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
1936 const char *func_str = __func__;
1937 u32 sid = ldp_sid_from_fd (fd);
1939 if ((errno = -ldp_init ()))
1942 if (sid != INVALID_SESSION_ID)
1944 vppcom_endpt_t *ep = 0;
1950 switch (addr->sa_family)
1953 ep->is_ip4 = VPPCOM_IS_IP4;
1955 (uint8_t *) & ((const struct sockaddr_in *) addr)->sin_addr;
1957 (uint16_t) ((const struct sockaddr_in *) addr)->sin_port;
1961 ep->is_ip4 = VPPCOM_IS_IP6;
1963 (uint8_t *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1965 (uint16_t) ((const struct sockaddr_in6 *) addr)->sin6_port;
1969 errno = EAFNOSUPPORT;
1975 func_str = "vppcom_session_sendto";
1978 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1979 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
1980 getpid (), fd, fd, func_str, sid, sid, buf, n,
1983 size = vppcom_session_sendto (sid, (void *) buf, n, flags, ep);
1992 func_str = "libc_sendto";
1995 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1996 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
1997 getpid (), fd, fd, func_str, buf, n, flags,
2000 size = libc_sendto (fd, buf, n, flags, addr, addr_len);
2008 int errno_val = errno;
2010 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2011 "rv %d, errno = %d", getpid (), fd, fd,
2012 func_str, size, errno_val);
2016 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2017 getpid (), fd, fd, size, size);
2023 recvfrom (int fd, void *__restrict buf, size_t n, int flags,
2024 __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
2027 const char *func_str;
2028 u32 sid = ldp_sid_from_fd (fd);
2030 if ((errno = -ldp_init ()))
2033 if (sid != INVALID_SESSION_ID)
2036 u8 src_addr[sizeof (struct sockaddr_in6)];
2038 func_str = "vppcom_session_recvfrom";
2041 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2042 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2043 getpid (), fd, fd, func_str, sid, sid, buf, n,
2048 size = vppcom_session_recvfrom (sid, buf, n, flags, &ep);
2051 size = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
2054 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
2064 func_str = "libc_recvfrom";
2067 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2068 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2069 getpid (), fd, fd, func_str, buf, n, flags,
2072 size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
2079 int errno_val = errno;
2081 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2082 "rv %d, errno = %d", getpid (), fd, fd,
2083 func_str, size, errno_val);
2087 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2088 getpid (), fd, fd, size, size);
2094 sendmsg (int fd, const struct msghdr * message, int flags)
2097 const char *func_str;
2098 u32 sid = ldp_sid_from_fd (fd);
2100 if ((errno = -ldp_init ()))
2103 if (sid != INVALID_SESSION_ID)
2105 func_str = __func__;
2107 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2113 func_str = "libc_sendmsg";
2116 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2117 "message %p, flags 0x%x",
2118 getpid (), fd, fd, func_str, message, flags);
2120 size = libc_sendmsg (fd, message, flags);
2127 int errno_val = errno;
2129 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2130 "rv %d, errno = %d", getpid (), fd, fd,
2131 func_str, size, errno_val);
2135 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2136 getpid (), fd, fd, size, size);
2143 sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
2146 const char *func_str;
2147 u32 sid = ldp_sid_from_fd (fd);
2149 if ((errno = -ldp_init ()))
2152 if (sid != INVALID_SESSION_ID)
2154 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2160 func_str = "libc_sendmmsg";
2163 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2164 "vmessages %p, vlen %u, flags 0x%x",
2165 getpid (), fd, fd, func_str, vmessages, vlen, flags);
2167 size = libc_sendmmsg (fd, vmessages, vlen, flags);
2174 int errno_val = errno;
2176 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2177 "rv %d, errno = %d", getpid (), fd, fd,
2178 func_str, size, errno_val);
2182 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2183 getpid (), fd, fd, size, size);
2190 recvmsg (int fd, struct msghdr * message, int flags)
2193 const char *func_str;
2194 u32 sid = ldp_sid_from_fd (fd);
2196 if ((errno = -ldp_init ()))
2199 if (sid != INVALID_SESSION_ID)
2201 func_str = __func__;
2203 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2209 func_str = "libc_recvmsg";
2212 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2213 "message %p, flags 0x%x",
2214 getpid (), fd, fd, func_str, message, flags);
2216 size = libc_recvmsg (fd, message, flags);
2223 int errno_val = errno;
2225 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2226 "rv %d, errno = %d", getpid (), fd, fd,
2227 func_str, size, errno_val);
2231 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2232 getpid (), fd, fd, size, size);
2239 recvmmsg (int fd, struct mmsghdr *vmessages,
2240 unsigned int vlen, int flags, struct timespec *tmo)
2243 const char *func_str;
2244 u32 sid = ldp_sid_from_fd (fd);
2246 if ((errno = -ldp_init ()))
2249 if (sid != INVALID_SESSION_ID)
2251 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2257 func_str = "libc_recvmmsg";
2260 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2261 "vmessages %p, vlen %u, flags 0x%x, tmo %p",
2262 getpid (), fd, fd, func_str, vmessages, vlen,
2265 size = libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
2272 int errno_val = errno;
2274 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2275 "rv %d, errno = %d", getpid (), fd, fd,
2276 func_str, size, errno_val);
2280 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2281 getpid (), fd, fd, size, size);
2288 getsockopt (int fd, int level, int optname,
2289 void *__restrict optval, socklen_t * __restrict optlen)
2292 const char *func_str = __func__;
2293 u32 sid = ldp_sid_from_fd (fd);
2294 u32 buflen = optlen ? (u32) * optlen : 0;
2296 if ((errno = -ldp_init ()))
2299 if (sid != INVALID_SESSION_ID)
2309 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_NODELAY]";
2311 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2313 getpid (), fd, fd, func_str, sid, sid);
2314 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_NODELAY,
2318 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_USER_MSS]";
2320 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2322 getpid (), fd, fd, func_str, sid, sid);
2323 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_USER_MSS,
2327 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPIDLE]";
2329 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2331 getpid (), fd, fd, func_str, sid, sid);
2332 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
2336 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPINTVL]";
2338 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2339 "sid %u (0x%x), SOL_TCP",
2340 getpid (), fd, fd, func_str, sid, sid);
2341 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
2345 if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
2348 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x), "
2349 "SOL_TCP, TCP_INFO, optval %p, "
2350 "optlen %d: #LDP-NOP#",
2351 getpid (), fd, fd, sid, sid,
2353 memset (optval, 0, *optlen);
2361 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2362 "sid %u (0x%x), SOL_TCP, "
2363 "optname %d unsupported!",
2364 getpid (), fd, fd, func_str, sid, sid, optname);
2372 func_str = "vppcom_session_attr[SOL_IPV6,GET_V6ONLY]";
2374 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2376 getpid (), fd, fd, func_str, sid, sid);
2377 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_V6ONLY,
2382 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2383 "sid %u (0x%x), SOL_IPV6, "
2384 "optname %d unsupported!",
2385 getpid (), fd, fd, func_str, sid, sid, optname);
2393 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ACCEPTCONN]";
2395 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2397 getpid (), fd, fd, func_str, sid, sid);
2398 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LISTEN,
2402 func_str = "vppcom_session_attr[SOL_SOCKET,GET_KEEPALIVE]";
2404 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2406 getpid (), fd, fd, func_str, sid, sid);
2407 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_KEEPALIVE,
2411 func_str = "vppcom_session_attr[SOL_SOCKET,GET_PROTOCOL]";
2413 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2415 getpid (), fd, fd, func_str, sid, sid);
2416 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PROTOCOL,
2418 *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
2421 func_str = "vppcom_session_attr[SOL_SOCKET,GET_TX_FIFO_LEN]";
2423 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2424 "sid %u (0x%x), optlen %d",
2425 getpid (), fd, fd, func_str, sid, sid, buflen);
2426 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TX_FIFO_LEN,
2430 func_str = "vppcom_session_attr[SOL_SOCKET,GET_RX_FIFO_LEN]";
2432 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2433 "sid %u (0x%x), optlen %d",
2434 getpid (), fd, fd, func_str, sid, sid, buflen);
2435 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_RX_FIFO_LEN,
2439 func_str = "vppcom_session_attr[SOL_SOCKET,GET_REUSEADDR]";
2441 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2443 getpid (), fd, fd, func_str, sid, sid);
2444 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REUSEADDR,
2448 func_str = "vppcom_session_attr[SOL_SOCKET,GET_BROADCAST]";
2450 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2452 getpid (), fd, fd, func_str, sid, sid);
2453 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_BROADCAST,
2457 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ERROR]";
2459 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2461 getpid (), fd, fd, func_str, sid, sid);
2462 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_ERROR,
2467 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2468 "sid %u (0x%x), SOL_SOCKET, "
2469 "optname %d unsupported!",
2470 getpid (), fd, fd, func_str, sid, sid, optname);
2478 if (rv != VPPCOM_OK)
2486 func_str = "libc_getsockopt";
2489 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2490 "optname %d, optval %p, optlen %d",
2491 getpid (), fd, fd, func_str, level, optname,
2494 rv = libc_getsockopt (fd, level, optname, optval, optlen);
2501 int errno_val = errno;
2503 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2504 "rv %d, errno = %d", getpid (), fd, fd,
2505 func_str, rv, errno_val);
2509 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2510 getpid (), fd, fd, rv, rv);
2516 setsockopt (int fd, int level, int optname,
2517 const void *optval, socklen_t optlen)
2520 const char *func_str = __func__;
2521 u32 sid = ldp_sid_from_fd (fd);
2523 if ((errno = -ldp_init ()))
2526 if (sid != INVALID_SESSION_ID)
2536 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_NODELAY]";
2538 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2540 getpid (), fd, fd, func_str, sid, sid);
2541 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_NODELAY,
2542 (void *) optval, &optlen);
2545 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_USER_MSS]";
2547 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2549 getpid (), fd, fd, func_str, sid, sid);
2550 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_USER_MSS,
2551 (void *) optval, &optlen);
2554 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPIDLE]";
2556 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2558 getpid (), fd, fd, func_str, sid, sid);
2559 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
2560 (void *) optval, &optlen);
2563 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPINTVL]";
2565 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2566 "sid %u (0x%x), SOL_TCP",
2567 getpid (), fd, fd, func_str, sid, sid);
2568 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
2569 (void *) optval, &optlen);
2573 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2574 "sid %u (0x%x), SOL_TCP, "
2575 "optname %d unsupported!",
2576 getpid (), fd, fd, func_str, sid, sid, optname);
2584 func_str = "vppcom_session_attr[SOL_IPV6,SET_V6ONLY]";
2586 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2588 getpid (), fd, fd, func_str, sid, sid);
2589 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_V6ONLY,
2590 (void *) optval, &optlen);
2594 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2595 "sid %u (0x%x), SOL_IPV6, "
2596 "optname %d unsupported!",
2597 getpid (), fd, fd, func_str, sid, sid, optname);
2605 func_str = "vppcom_session_attr[SOL_SOCKET,SET_KEEPALIVE]";
2607 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2609 getpid (), fd, fd, func_str, sid, sid);
2610 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_KEEPALIVE,
2611 (void *) optval, &optlen);
2614 func_str = "vppcom_session_attr[SOL_SOCKET,SET_REUSEADDR]";
2616 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2618 getpid (), fd, fd, func_str, sid, sid);
2619 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_REUSEADDR,
2620 (void *) optval, &optlen);
2623 func_str = "vppcom_session_attr[SOL_SOCKET,SET_BROADCAST]";
2625 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2627 getpid (), fd, fd, func_str, sid, sid);
2628 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_BROADCAST,
2629 (void *) optval, &optlen);
2633 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2634 "sid %u (0x%x), SOL_SOCKET, "
2635 "optname %d unsupported!",
2636 getpid (), fd, fd, func_str, sid, sid, optname);
2644 if (rv != VPPCOM_OK)
2652 func_str = "libc_setsockopt";
2655 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2656 "optname %d, optval %p, optlen %d",
2657 getpid (), fd, fd, func_str, level, optname,
2660 rv = libc_setsockopt (fd, level, optname, optval, optlen);
2667 int errno_val = errno;
2669 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2670 "rv %d, errno = %d", getpid (), fd, fd,
2671 func_str, rv, errno_val);
2675 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2676 getpid (), fd, fd, rv, rv);
2682 listen (int fd, int n)
2685 u32 sid = ldp_sid_from_fd (fd);
2687 if ((errno = -ldp_init ()))
2690 if (sid != INVALID_SESSION_ID)
2692 LDBG (0, "fd %d (0x%x): calling vppcom_session_listen():"
2693 " sid %u (0x%x), n %d", fd, fd, sid, sid, n);
2695 rv = vppcom_session_listen (sid, n);
2696 if (rv != VPPCOM_OK)
2704 LDBG (0, "fd %d (0x%x): calling libc_listen(): n %d", fd, fd, n);
2706 rv = libc_listen (fd, n);
2709 LDBG (1, "fd %d (0x%x): returning %d (0x%x)", fd, fd, rv, rv);
2714 ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
2715 socklen_t * __restrict addr_len, int flags)
2718 u32 listen_sid = ldp_sid_from_fd (listen_fd);
2721 if ((errno = -ldp_init ()))
2724 if (listen_sid != INVALID_SESSION_ID)
2727 u8 src_addr[sizeof (struct sockaddr_in6)];
2728 memset (&ep, 0, sizeof (ep));
2731 LDBG (0, "listen fd %d (0x%x): calling vppcom_session_accept:"
2732 " listen sid %u (0x%x), ep %p, flags 0x%x", listen_fd,
2733 listen_fd, listen_sid, listen_sid, ep, flags);
2735 accept_sid = vppcom_session_accept (listen_sid, &ep, flags);
2738 errno = -accept_sid;
2743 rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
2744 if (rv != VPPCOM_OK)
2746 (void) vppcom_session_close ((u32) accept_sid);
2752 rv = ldp_fd_alloc ((u32) accept_sid);
2755 (void) vppcom_session_close ((u32) accept_sid);
2764 LDBG (0, "listen fd %d (0x%x): calling libc_accept4(): "
2765 "addr %p, addr_len %p, flags 0x%x", listen_fd,
2766 listen_fd, addr, addr_len, flags);
2768 rv = libc_accept4 (listen_fd, addr, addr_len, flags);
2771 LDBG (1, "listen fd %d (0x%x): returning %d (0x%x)", listen_fd, listen_fd,
2778 accept4 (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len,
2781 return ldp_accept4 (fd, addr, addr_len, flags);
2785 accept (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
2787 return ldp_accept4 (fd, addr, addr_len, 0);
2791 shutdown (int fd, int how)
2794 const char *func_str;
2795 u32 sid = ldp_sid_from_fd (fd);
2797 if ((errno = -ldp_init ()))
2800 if (sid != INVALID_SESSION_ID)
2802 func_str = "vppcom_session_close[TODO]";
2807 func_str = "libc_shutdown";
2810 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): how %d",
2811 getpid (), fd, fd, func_str, how);
2813 rv = libc_shutdown (fd, how);
2820 int errno_val = errno;
2822 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2823 "rv %d, errno = %d", getpid (), fd, fd,
2824 func_str, rv, errno_val);
2828 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2829 getpid (), fd, fd, rv, rv);
2835 epoll_create1 (int flags)
2837 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
2838 const char *func_str;
2841 if ((errno = -ldp_init ()))
2844 if (ldp->vcl_needs_real_epoll)
2846 rv = libc_epoll_create1 (flags);
2847 ldp->vcl_needs_real_epoll = 0;
2848 ldpw->vcl_mq_epfd = rv;
2849 LDBG (0, "created vcl epfd %u", rv);
2852 func_str = "vppcom_epoll_create";
2854 LDBG (1, "calling %s()", func_str);
2856 rv = vppcom_epoll_create ();
2858 if (PREDICT_FALSE (rv < 0))
2864 rv = ldp_fd_alloc ((u32) rv);
2870 int errno_val = errno;
2872 clib_warning ("LDP<%d>: ERROR: %s() failed! "
2873 "rv %d, errno = %d",
2874 getpid (), func_str, rv, errno_val);
2878 clib_warning ("LDP<%d>: returning epfd %d (0x%x)", getpid (), rv, rv);
2884 epoll_create (int size)
2886 return epoll_create1 (0);
2890 epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
2892 u32 vep_idx = ldp_sid_from_fd (epfd), sid;
2893 const char *func_str;
2896 if ((errno = -ldp_init ()))
2899 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
2901 /* The LDP epoll_create1 always creates VCL epfd's.
2902 * The app should never have a kernel base epoll fd unless it
2903 * was acquired outside of the LD_PRELOAD process context.
2904 * In any case, if we get one, punt it to libc_epoll_ctl.
2906 func_str = "libc_epoll_ctl";
2908 LDBG (1, "epfd %d (0x%x): calling %s(): op %d, fd %d (0x%x),"
2909 " event %p", epfd, epfd, func_str, op, fd, fd, event);
2911 rv = libc_epoll_ctl (epfd, op, fd, event);
2915 sid = ldp_sid_from_fd (fd);
2917 LDBG (0, "epfd %d (0x%x), vep_idx %d (0x%x), sid %d (0x%x)",
2918 epfd, epfd, vep_idx, vep_idx, sid, sid);
2920 if (sid != INVALID_SESSION_ID)
2922 func_str = "vppcom_epoll_ctl";
2924 LDBG (1, "epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
2925 " op %d, sid %u (0x%x), event %p", epfd, epfd,
2926 func_str, vep_idx, vep_idx, sid, sid, event);
2928 rv = vppcom_epoll_ctl (vep_idx, op, sid, event);
2929 if (rv != VPPCOM_OK)
2938 u32 size = sizeof (epfd);
2940 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
2941 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0,
2943 LDBG (1, "epfd %d (0x%x), vep_idx %d (0x%x): %s() "
2944 "returned libc_epfd %d (0x%x)", epfd, epfd,
2945 vep_idx, vep_idx, func_str, libc_epfd, libc_epfd);
2949 func_str = "libc_epoll_create1";
2951 LDBG (1, "epfd %d (0x%x), vep_idx %d (0x%x): "
2952 "calling %s(): EPOLL_CLOEXEC", epfd, epfd,
2953 vep_idx, vep_idx, func_str);
2955 libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
2962 func_str = "vppcom_session_attr[SET_LIBC_EPFD]";
2963 LDBG (1, "epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
2964 " VPPCOM_ATTR_SET_LIBC_EPFD, libc_epfd %d (0x%x), size %d",
2965 epfd, epfd, func_str, vep_idx, vep_idx, libc_epfd,
2968 rv = vppcom_session_attr (vep_idx, VPPCOM_ATTR_SET_LIBC_EPFD,
2977 else if (PREDICT_FALSE (libc_epfd < 0))
2984 func_str = "libc_epoll_ctl";
2986 LDBG (1, "epfd %d (0x%x): calling %s(): libc_epfd %d (0x%x), "
2987 "op %d, fd %d (0x%x), event %p", epfd, epfd, func_str,
2988 libc_epfd, libc_epfd, op, fd, fd, event);
2990 rv = libc_epoll_ctl (libc_epfd, op, fd, event);
2998 int errno_val = errno;
3000 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
3001 "rv %d, errno = %d", getpid (), fd, fd,
3002 func_str, rv, errno_val);
3006 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
3007 getpid (), fd, fd, rv, rv);
3013 ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
3014 int timeout, const sigset_t * sigmask)
3016 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
3017 double time_to_wait = (double) 0, time_out, now = 0;
3018 u32 vep_idx = ldp_sid_from_fd (epfd);
3019 int libc_epfd, rv = 0;
3020 const char *func_str;
3022 if ((errno = -ldp_init ()))
3025 if (PREDICT_FALSE (!events || (timeout < -1)))
3031 if (epfd == ldpw->vcl_mq_epfd)
3032 return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
3034 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
3036 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): bad vep_idx %d (0x%x)!",
3037 getpid (), epfd, epfd, vep_idx, vep_idx);
3042 time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0);
3043 time_out = clib_time_now (&ldpw->clib_time) + time_to_wait;
3045 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
3046 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
3047 if (PREDICT_FALSE (libc_epfd < 0))
3054 LDBG (2, "epfd %d (0x%x): vep_idx %d (0x%x), libc_epfd %d (0x%x), "
3055 "events %p, maxevents %d, timeout %d, sigmask %p: time_to_wait %.02f",
3056 epfd, epfd, vep_idx, vep_idx, libc_epfd, libc_epfd, events,
3057 maxevents, timeout, sigmask, time_to_wait, time_out);
3060 if (!ldpw->epoll_wait_vcl)
3062 func_str = "vppcom_epoll_wait";
3064 LDBG (3, "epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3065 " events %p, maxevents %d", epfd, epfd, func_str,
3066 vep_idx, vep_idx, events, maxevents);
3068 rv = vppcom_epoll_wait (vep_idx, events, maxevents, 0);
3071 ldpw->epoll_wait_vcl = 1;
3082 ldpw->epoll_wait_vcl = 0;
3086 func_str = "libc_epoll_pwait";
3088 LDBG (3, "epfd %d (0x%x): calling %s(): libc_epfd %d "
3089 "(0x%x), events %p, maxevents %d, sigmask %p",
3090 epfd, epfd, func_str, libc_epfd, libc_epfd, events,
3091 maxevents, sigmask);
3093 rv = libc_epoll_pwait (libc_epfd, events, maxevents, 0, sigmask);
3099 now = clib_time_now (&ldpw->clib_time);
3101 while (now < time_out);
3110 int errno_val = errno;
3112 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): %s() failed! "
3113 "rv %d, errno = %d", getpid (), epfd, epfd,
3114 func_str, rv, errno_val);
3118 clib_warning ("LDP<%d>: epfd %d (0x%x): returning %d (0x%x)",
3119 getpid (), epfd, epfd, rv, rv);
3125 epoll_pwait (int epfd, struct epoll_event *events,
3126 int maxevents, int timeout, const sigset_t * sigmask)
3128 return ldp_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
3132 epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
3134 return ldp_epoll_pwait (epfd, events, maxevents, timeout, NULL);
3138 poll (struct pollfd *fds, nfds_t nfds, int timeout)
3140 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
3141 const char *func_str = __func__;
3142 int rv, i, n_revents = 0;
3145 double wait_for_time;
3147 LDBG (3, "fds %p, nfds %d, timeout %d", fds, nfds, timeout);
3150 wait_for_time = (f64) timeout / 1000;
3154 for (i = 0; i < nfds; i++)
3159 LDBG (3, "fds[%d] fd %d (0x%0x) events = 0x%x revents = 0x%x",
3160 i, fds[i].fd, fds[i].fd, fds[i].events, fds[i].revents);
3162 sid = ldp_sid_from_fd (fds[i].fd);
3163 if (sid != INVALID_SESSION_ID)
3165 fds[i].fd = -fds[i].fd;
3166 vec_add2 (ldpw->vcl_poll, vp, 1);
3169 vp->events = fds[i].events;
3170 #ifdef __USE_XOPEN2K
3171 if (fds[i].events & POLLRDNORM)
3172 vp->events |= POLLIN;
3173 if (fds[i].events & POLLWRNORM)
3174 vp->events |= POLLOUT;
3176 vp->revents = fds[i].revents;
3180 vec_add1 (ldpw->libc_poll, fds[i]);
3181 vec_add1 (ldpw->libc_poll_idxs, i);
3187 if (vec_len (ldpw->vcl_poll))
3189 func_str = "vppcom_poll";
3191 LDBG (3, "calling %s(): vcl_poll %p, n_sids %u (0x%x): "
3192 "n_libc_fds %u", func_str, ldpw->vcl_poll,
3193 vec_len (ldpw->vcl_poll), vec_len (ldpw->vcl_poll),
3194 vec_len (ldpw->libc_poll));
3196 rv = vppcom_poll (ldpw->vcl_poll, vec_len (ldpw->vcl_poll), 0);
3207 if (vec_len (ldpw->libc_poll))
3209 func_str = "libc_poll";
3211 LDBG (3, "calling %s(): fds %p, nfds %u: n_sids %u",
3212 fds, nfds, vec_len (ldpw->vcl_poll));
3214 rv = libc_poll (ldpw->libc_poll, vec_len (ldpw->libc_poll), 0);
3227 while ((wait_for_time == -1) ||
3228 (clib_time_now (&ldpw->clib_time) < wait_for_time));
3232 vec_foreach (vp, ldpw->vcl_poll)
3234 fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd;
3235 fds[vp->fds_ndx].revents = vp->revents;
3236 #ifdef __USE_XOPEN2K
3237 if ((fds[vp->fds_ndx].revents & POLLIN) &&
3238 (fds[vp->fds_ndx].events & POLLRDNORM))
3239 fds[vp->fds_ndx].revents |= POLLRDNORM;
3240 if ((fds[vp->fds_ndx].revents & POLLOUT) &&
3241 (fds[vp->fds_ndx].events & POLLWRNORM))
3242 fds[vp->fds_ndx].revents |= POLLWRNORM;
3245 vec_reset_length (ldpw->vcl_poll);
3247 for (i = 0; i < vec_len (ldpw->libc_poll); i++)
3249 fds[ldpw->libc_poll_idxs[i]].revents = ldpw->libc_poll[i].revents;
3251 vec_reset_length (ldpw->libc_poll_idxs);
3252 vec_reset_length (ldpw->libc_poll);
3258 int errno_val = errno;
3260 clib_warning ("LDP<%d>: ERROR: %s() failed! "
3261 "rv %d, errno = %d", getpid (),
3262 func_str, rv, errno_val);
3267 clib_warning ("LDP<%d>: returning %d (0x%x): n_sids %u, "
3268 "n_libc_fds %d", getpid (), rv, rv,
3269 vec_len (ldpw->vcl_poll), vec_len (ldpw->libc_poll));
3271 for (i = 0; i < nfds; i++)
3276 clib_warning ("LDP<%d>: fds[%d].fd %d (0x%0x), "
3277 ".events = 0x%x, .revents = 0x%x",
3278 getpid (), i, fds[i].fd, fds[i].fd,
3279 fds[i].events, fds[i].revents);
3290 ppoll (struct pollfd *fds, nfds_t nfds,
3291 const struct timespec *timeout, const sigset_t * sigmask)
3293 if ((errno = -ldp_init ()))
3296 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
3304 void CONSTRUCTOR_ATTRIBUTE ldp_constructor (void);
3306 void DESTRUCTOR_ATTRIBUTE ldp_destructor (void);
3309 * This function is called when the library is loaded
3312 ldp_constructor (void)
3314 swrap_constructor ();
3315 if (ldp_init () != 0)
3316 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
3318 else if (LDP_DEBUG > 0)
3319 clib_warning ("LDP<%d>: LDP constructor: done!\n", getpid ());
3323 * This function is called when the library is unloaded
3326 ldp_destructor (void)
3328 swrap_destructor ();
3332 /* Don't use clib_warning() here because that calls writev()
3333 * which will call ldp_init().
3336 printf ("%s:%d: LDP<%d>: LDP destructor: done!\n",
3337 __func__, __LINE__, getpid ());
3342 * fd.io coding-style-patch-verification: ON
3345 * eval: (c-set-style "gnu")