/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
+ * Copyright (c) 2016-2019 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+#ifdef HAVE_GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <stdarg.h>
#include <sys/resource.h>
#include <netinet/tcp.h>
+#include <netinet/udp.h>
#include <vcl/ldp_socket_wrapper.h>
#include <vcl/ldp.h>
#include <sys/time.h>
-#include <vcl/vppcom.h>
+#include <vcl/vcl_locked.h>
#include <vppinfra/time.h>
#include <vppinfra/bitmap.h>
#include <vppinfra/lock.h>
#define LDP_MAX_NWORKERS 32
-typedef struct ldp_fd_entry_
-{
- u32 session_index;
- u32 fd;
- u32 fd_index;
-} ldp_fd_entry_t;
+#ifdef HAVE_GNU_SOURCE
+#define SOCKADDR_GET_SA(__addr) __addr.__sockaddr__;
+#else
+#define SOCKADDR_GET_SA(__addr) _addr;
+#endif
+
+#ifndef UDP_SEGMENT
+#define UDP_SEGMENT 103
+#endif
+#ifndef SO_ORIGINAL_DST
+/* from <linux/netfilter_ipv4.h> */
+#define SO_ORIGINAL_DST 80
+#endif
typedef struct ldp_worker_ctx_
{
u8 *io_buffer;
clib_bitmap_t *rd_bitmap;
clib_bitmap_t *wr_bitmap;
clib_bitmap_t *ex_bitmap;
- clib_bitmap_t *sid_rd_bitmap;
- clib_bitmap_t *sid_wr_bitmap;
- clib_bitmap_t *sid_ex_bitmap;
+ clib_bitmap_t *si_rd_bitmap;
+ clib_bitmap_t *si_wr_bitmap;
+ clib_bitmap_t *si_ex_bitmap;
clib_bitmap_t *libc_rd_bitmap;
clib_bitmap_t *libc_wr_bitmap;
clib_bitmap_t *libc_ex_bitmap;
- u8 select_vcl;
/*
* Poll state
* Epoll state
*/
u8 epoll_wait_vcl;
+ u8 mq_epfd_added;
int vcl_mq_epfd;
} ldp_worker_ctx_t;
+/* clib_bitmap_t, fd_mask and vcl_si_set are used interchangeably. Make sure
+ * they are the same size */
+STATIC_ASSERT (sizeof (clib_bitmap_t) == sizeof (fd_mask),
+ "ldp bitmap size mismatch");
+STATIC_ASSERT (sizeof (vcl_si_set) == sizeof (fd_mask),
+ "ldp bitmap size mismatch");
+
typedef struct
{
ldp_worker_ctx_t *workers;
int init;
char app_name[LDP_APP_NAME_MAX];
- u32 sid_bit_val;
- u32 sid_bit_mask;
+ u32 vlsh_bit_val;
+ u32 vlsh_bit_mask;
u32 debug;
- ldp_fd_entry_t *fd_pool;
- clib_rwlock_t fd_table_lock;
- uword *session_index_to_fd_table;
/** vcl needs next epoll_create to go to libc_epoll */
u8 vcl_needs_real_epoll;
+
+ /**
+ * crypto state used only for testing
+ */
+ u8 transparent_tls;
+ u32 ckpair_index;
} ldp_main_t;
#define LDP_DEBUG ldp->debug
#define LDBG(_lvl, _fmt, _args...) \
if (ldp->debug > _lvl) \
- clib_warning ("ldp<%d>: " _fmt, getpid(), ##_args)
+ { \
+ int errno_saved = errno; \
+ fprintf (stderr, "ldp<%d>: " _fmt "\n", getpid(), ##_args); \
+ errno = errno_saved; \
+ }
static ldp_main_t ldp_main = {
- .sid_bit_val = (1 << LDP_SID_BIT_MIN),
- .sid_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
+ .vlsh_bit_val = (1 << LDP_SID_BIT_MIN),
+ .vlsh_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
.debug = LDP_DEBUG_INIT,
+ .transparent_tls = 0,
+ .ckpair_index = ~0,
};
static ldp_main_t *ldp = &ldp_main;
static inline void
ldp_set_app_name (char *app_name)
{
- int rv = snprintf (ldp->app_name, LDP_APP_NAME_MAX,
- "ldp-%d-%s", getpid (), app_name);
-
- if (rv >= LDP_APP_NAME_MAX)
- app_name[LDP_APP_NAME_MAX - 1] = 0;
+ snprintf (ldp->app_name, LDP_APP_NAME_MAX, "%s-ldp-%d", app_name, getpid ());
}
static inline char *
ldp_get_app_name ()
{
if (ldp->app_name[0] == '\0')
- ldp_set_app_name ("app");
+ ldp_set_app_name (program_invocation_short_name);
return ldp->app_name;
}
-static int
-ldp_fd_alloc (u32 sid)
-{
- ldp_fd_entry_t *fde;
-
- clib_rwlock_writer_lock (&ldp->fd_table_lock);
- if (pool_elts (ldp->fd_pool) >= (1ULL << 32) - ldp->sid_bit_val)
- {
- clib_rwlock_writer_unlock (&ldp->fd_table_lock);
- return -1;
- }
- pool_get (ldp->fd_pool, fde);
- fde->session_index = vppcom_session_index (sid);
- fde->fd_index = fde - ldp->fd_pool;
- fde->fd = fde->fd_index + ldp->sid_bit_val;
- hash_set (ldp->session_index_to_fd_table, fde->session_index, fde->fd);
- clib_rwlock_writer_unlock (&ldp->fd_table_lock);
- return fde->fd;
-}
-
-static ldp_fd_entry_t *
-ldp_fd_entry_get_w_lock (u32 fd_index)
-{
- clib_rwlock_reader_lock (&ldp->fd_table_lock);
- if (pool_is_free_index (ldp->fd_pool, fd_index))
- return 0;
-
- return pool_elt_at_index (ldp->fd_pool, fd_index);
-}
-
-static inline int
-ldp_fd_from_sid (u32 sid)
-{
- uword *fdp;
- int fd;
-
- clib_rwlock_reader_lock (&ldp->fd_table_lock);
- fdp = hash_get (ldp->session_index_to_fd_table, vppcom_session_index (sid));
- fd = fdp ? *fdp : -EMFILE;
- clib_rwlock_reader_unlock (&ldp->fd_table_lock);
-
- return fd;
-}
-
static inline int
-ldp_fd_is_sid (int fd)
+ldp_vlsh_to_fd (vls_handle_t vlsh)
{
- return fd >= ldp->sid_bit_val;
+ return (vlsh + ldp->vlsh_bit_val);
}
-static inline u32
-ldp_sid_from_fd (int fd)
+static inline vls_handle_t
+ldp_fd_to_vlsh (int fd)
{
- u32 fd_index, session_index;
- ldp_fd_entry_t *fde;
-
- if (!ldp_fd_is_sid (fd))
- return INVALID_SESSION_ID;
-
- fd_index = fd - ldp->sid_bit_val;
- fde = ldp_fd_entry_get_w_lock (fd_index);
- if (!fde)
- {
- LDBG (0, "unknown fd %d", fd);
- clib_rwlock_reader_unlock (&ldp->fd_table_lock);
- return INVALID_SESSION_ID;
- }
- session_index = fde->session_index;
- clib_rwlock_reader_unlock (&ldp->fd_table_lock);
+ if (fd < ldp->vlsh_bit_val)
+ return VLS_INVALID_HANDLE;
- return vppcom_session_handle (session_index);
+ return (fd - ldp->vlsh_bit_val);
}
static void
-ldp_fd_free_w_sid (u32 sid)
+ldp_alloc_workers (void)
{
- ldp_fd_entry_t *fde;
- u32 fd_index;
- int fd;
-
- fd = ldp_fd_from_sid (sid);
- if (!fd)
+ if (ldp->workers)
return;
-
- fd_index = fd - ldp->sid_bit_val;
- fde = ldp_fd_entry_get_w_lock (fd_index);
- if (fde)
- {
- hash_unset (ldp->session_index_to_fd_table, fde->session_index);
- pool_put (ldp->fd_pool, fde);
- }
- clib_rwlock_writer_unlock (&ldp->fd_table_lock);
+ pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
}
-static inline int
-ldp_init (void)
+static void
+ldp_init_cfg (void)
{
- ldp_worker_ctx_t *ldpw;
- int rv;
-
- if (PREDICT_TRUE (ldp->init))
- return 0;
-
- ldp->init = 1;
- ldp->vcl_needs_real_epoll = 1;
- rv = vppcom_app_create (ldp_get_app_name ());
- if (rv != VPPCOM_OK)
- {
- ldp->vcl_needs_real_epoll = 0;
- if (rv == VPPCOM_EEXIST)
- return 0;
- LDBG (2, "\nERROR: ldp_init: vppcom_app_create()"
- " failed! rv = %d (%s)\n", rv, vppcom_retval_str (rv));
- ldp->init = 0;
- return rv;
- }
- ldp->vcl_needs_real_epoll = 0;
- pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
- ldpw = ldp_worker_get_current ();
-
char *env_var_str = getenv (LDP_ENV_DEBUG);
if (env_var_str)
{
u32 sb;
if (sscanf (env_var_str, "%u", &sb) != 1)
{
- clib_warning ("LDP<%d>: WARNING: Invalid LDP sid bit specified in"
- " the env var " LDP_ENV_SID_BIT " (%s)! sid bit "
- "value %d (0x%x)", getpid (), env_var_str,
- ldp->sid_bit_val, ldp->sid_bit_val);
+ LDBG (0, "WARNING: Invalid LDP sid bit specified in the env var "
+ LDP_ENV_SID_BIT " (%s)! sid bit value %d (0x%x)", env_var_str,
+ ldp->vlsh_bit_val, ldp->vlsh_bit_val);
}
else if (sb < LDP_SID_BIT_MIN)
{
- ldp->sid_bit_val = (1 << LDP_SID_BIT_MIN);
- ldp->sid_bit_mask = ldp->sid_bit_val - 1;
+ ldp->vlsh_bit_val = (1 << LDP_SID_BIT_MIN);
+ ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
- clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
- " env var " LDP_ENV_SID_BIT " (%s) is too small. "
- "Using LDP_SID_BIT_MIN (%d)! sid bit value %d (0x%x)",
- getpid (), sb, env_var_str, LDP_SID_BIT_MIN,
- ldp->sid_bit_val, ldp->sid_bit_val);
+ LDBG (0, "WARNING: LDP sid bit (%u) specified in the env var "
+ LDP_ENV_SID_BIT " (%s) is too small. Using LDP_SID_BIT_MIN"
+ " (%d)! sid bit value %d (0x%x)", sb, env_var_str,
+ LDP_SID_BIT_MIN, ldp->vlsh_bit_val, ldp->vlsh_bit_val);
}
else if (sb > LDP_SID_BIT_MAX)
{
- ldp->sid_bit_val = (1 << LDP_SID_BIT_MAX);
- ldp->sid_bit_mask = ldp->sid_bit_val - 1;
+ ldp->vlsh_bit_val = (1 << LDP_SID_BIT_MAX);
+ ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
- clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
- " env var " LDP_ENV_SID_BIT " (%s) is too big. Using"
- " LDP_SID_BIT_MAX (%d)! sid bit value %d (0x%x)",
- getpid (), sb, env_var_str, LDP_SID_BIT_MAX,
- ldp->sid_bit_val, ldp->sid_bit_val);
+ LDBG (0, "WARNING: LDP sid bit (%u) specified in the env var "
+ LDP_ENV_SID_BIT " (%s) is too big. Using LDP_SID_BIT_MAX"
+ " (%d)! sid bit value %d (0x%x)", sb, env_var_str,
+ LDP_SID_BIT_MAX, ldp->vlsh_bit_val, ldp->vlsh_bit_val);
}
else
{
- ldp->sid_bit_val = (1 << sb);
- ldp->sid_bit_mask = ldp->sid_bit_val - 1;
+ ldp->vlsh_bit_val = (1 << sb);
+ ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
LDBG (0, "configured LDP sid bit (%u) from "
LDP_ENV_SID_BIT "! sid bit value %d (0x%x)", sb,
- ldp->sid_bit_val, ldp->sid_bit_val);
+ ldp->vlsh_bit_val, ldp->vlsh_bit_val);
+ }
+
+ /* Make sure there are enough bits in the fd set for vcl sessions */
+ if (ldp->vlsh_bit_val > FD_SETSIZE / 2)
+ {
+ /* Only valid for select/pselect, so just WARNING and not exit */
+ LDBG (0,
+ "WARNING: LDP vlsh bit value %d > FD_SETSIZE/2 %d, "
+ "select/pselect not supported now!",
+ ldp->vlsh_bit_val, FD_SETSIZE / 2);
}
}
+ env_var_str = getenv (LDP_ENV_TLS_TRANS);
+ if (env_var_str)
+ {
+ ldp->transparent_tls = 1;
+ }
+}
+
+static int
+ldp_init (void)
+{
+ ldp_worker_ctx_t *ldpw;
+ int rv;
+
+ if (ldp->init)
+ {
+ LDBG (0, "LDP is initialized already");
+ return 0;
+ }
+
+ ldp_init_cfg ();
+ ldp->init = 1;
+ ldp->vcl_needs_real_epoll = 1;
+ rv = vls_app_create (ldp_get_app_name ());
+ if (rv != VPPCOM_OK)
+ {
+ ldp->vcl_needs_real_epoll = 0;
+ if (rv == VPPCOM_EEXIST)
+ return 0;
+ LDBG (2,
+ "\nERROR: ldp_init: vppcom_app_create()"
+ " failed! rv = %d (%s)\n",
+ rv, vppcom_retval_str (rv));
+ ldp->init = 0;
+ return rv;
+ }
+ ldp->vcl_needs_real_epoll = 0;
+ ldp_alloc_workers ();
+ ldpw = ldp_worker_get_current ();
+
+ pool_foreach (ldpw, ldp->workers) {
+ clib_memset (&ldpw->clib_time, 0, sizeof (ldpw->clib_time));
+ }
- clib_time_init (&ldpw->clib_time);
- clib_rwlock_init (&ldp->fd_table_lock);
LDBG (0, "LDP initialization: done!");
return 0;
}
+#define ldp_init_check() \
+ if (PREDICT_FALSE (!ldp->init)) \
+ { \
+ if ((errno = -ldp_init ())) \
+ return -1; \
+ }
+
int
close (int fd)
{
- int rv, refcnt;
- u32 sid = ldp_sid_from_fd (fd);
+ vls_handle_t vlsh;
+ int rv, epfd;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
- int epfd;
-
- epfd = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
+ epfd = vls_attr (vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
if (epfd > 0)
{
- LDBG (0, "fd %d (0x%x): calling libc_close: epfd %u (0x%x)",
- fd, fd, epfd, epfd);
+ ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
+ u32 size = sizeof (epfd);
- rv = libc_close (epfd);
- if (rv < 0)
- {
- u32 size = sizeof (epfd);
- epfd = 0;
+ LDBG (0, "fd %d: calling libc_close: epfd %u", fd, epfd);
- (void) vppcom_session_attr (sid, VPPCOM_ATTR_SET_LIBC_EPFD,
- &epfd, &size);
- }
+ libc_close (epfd);
+ ldpw->mq_epfd_added = 0;
+
+ epfd = 0;
+ (void) vls_attr (vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &epfd, &size);
}
else if (PREDICT_FALSE (epfd < 0))
{
goto done;
}
- LDBG (0, "fd %d (0x%x): calling vppcom_session_close: sid %u (0x%x)",
- fd, fd, sid, sid);
+ LDBG (0, "fd %d: calling vls_close: vlsh %u", fd, vlsh);
- refcnt = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REFCNT, 0, 0);
- rv = vppcom_session_close (sid);
+ rv = vls_close (vlsh);
if (rv != VPPCOM_OK)
{
errno = -rv;
rv = -1;
}
- if (refcnt == 1)
- ldp_fd_free_w_sid (sid);
}
else
{
- LDBG (0, "fd %d (0x%x): calling libc_close", fd, fd);
+ LDBG (0, "fd %d: calling libc_close", fd);
rv = libc_close (fd);
}
done:
-
- LDBG (1, "fd %d (0x%x): returning %d (0x%x)", fd, fd, rv, rv);
return rv;
}
ssize_t
read (int fd, void *buf, size_t nbytes)
{
+ vls_handle_t vlsh;
ssize_t size;
- u32 sid = ldp_sid_from_fd (fd);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
- LDBG (2, "fd %d (0x%x): calling vppcom_session_read(): sid %u (0x%x),"
- " buf %p, nbytes %u", fd, fd, sid, sid, buf, nbytes);
-
- size = vppcom_session_read (sid, buf, nbytes);
+ size = vls_read (vlsh, buf, nbytes);
if (size < 0)
{
errno = -size;
}
else
{
- LDBG (2, "fd %d (0x%x): calling libc_read(): buf %p, nbytes %u",
- fd, fd, buf, nbytes);
-
size = libc_read (fd, buf, nbytes);
}
- LDBG (2, "fd %d (0x%x): returning %d (0x%x)", fd, fd, size, size);
return size;
}
ssize_t
readv (int fd, const struct iovec * iov, int iovcnt)
{
- ssize_t size = 0;
- u32 sid = ldp_sid_from_fd (fd);
int rv = 0, i, total = 0;
+ vls_handle_t vlsh;
+ ssize_t size = 0;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
- do
+ for (i = 0; i < iovcnt; ++i)
{
- for (i = 0; i < iovcnt; ++i)
+ rv = vls_read (vlsh, iov[i].iov_base, iov[i].iov_len);
+ if (rv <= 0)
+ break;
+ else
{
- LDBG (2, "fd %d (0x%x): calling vppcom_session_read() [%d]:"
- " sid %u (0x%x), iov %p, iovcnt %d, total %d", fd, fd, i,
- sid, sid, iov, iovcnt, total);
-
- rv = vppcom_session_read (sid, iov[i].iov_base, iov[i].iov_len);
- if (rv < 0)
+ total += rv;
+ if (rv < iov[i].iov_len)
break;
- else
- {
- total += rv;
- if (rv < iov[i].iov_len)
- {
- LDBG (2, "fd %d (0x%x): rv (%d) < iov[%d].iov_len (%d)",
- fd, fd, rv, i, iov[i].iov_len);
- break;
- }
- }
}
}
- while ((rv >= 0) && (total == 0));
-
- if (rv < 0)
+ if (rv < 0 && total == 0)
{
errno = -rv;
size = -1;
}
else
{
- LDBG (2, "fd %d (0x%x): calling libc_readv(): iov %p, iovcnt %d", fd,
- fd, iov, iovcnt);
-
size = libc_readv (fd, iov, iovcnt);
}
-
- LDBG (2, "fd %d (0x%x): returning %d (0x%x)", fd, fd, size, size);
return size;
}
ssize_t
write (int fd, const void *buf, size_t nbytes)
{
+ vls_handle_t vlsh;
ssize_t size = 0;
- u32 sid = ldp_sid_from_fd (fd);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
- LDBG (2, "fd %d (0x%x): calling vppcom_session_write(): sid %u (0x%x), "
- "buf %p, nbytes %u", fd, fd, sid, sid, buf, nbytes);
-
- size = vppcom_session_write (sid, (void *) buf, nbytes);
+ size = vls_write_msg (vlsh, (void *) buf, nbytes);
if (size < 0)
{
errno = -size;
}
else
{
- LDBG (2, "fd %d (0x%x): calling libc_write(): buf %p, nbytes %u",
- fd, fd, buf, nbytes);
-
size = libc_write (fd, buf, nbytes);
}
- LDBG (2, "fd %d (0x%x): returning %d (0x%x)", fd, fd, size, size);
return size;
}
ssize_t
writev (int fd, const struct iovec * iov, int iovcnt)
{
- const char *func_str;
ssize_t size = 0, total = 0;
- u32 sid = ldp_sid_from_fd (fd);
+ vls_handle_t vlsh;
int i, rv = 0;
- /*
- * Use [f]printf() instead of clib_warning() to prevent recursion SIGSEGV.
- */
-
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
- func_str = "vppcom_session_write";
- do
+ for (i = 0; i < iovcnt; ++i)
{
- for (i = 0; i < iovcnt; ++i)
+ rv = vls_write_msg (vlsh, iov[i].iov_base, iov[i].iov_len);
+ if (rv < 0)
+ break;
+ else
{
- if (LDP_DEBUG > 4)
- printf ("%s:%d: LDP<%d>: fd %d (0x%x): calling %s() [%d]: "
- "sid %u (0x%x), buf %p, nbytes %ld, total %ld",
- __func__, __LINE__, getpid (), fd, fd, func_str,
- i, sid, sid, iov[i].iov_base, iov[i].iov_len, total);
-
- rv = vppcom_session_write (sid, iov[i].iov_base,
- iov[i].iov_len);
- if (rv < 0)
+ total += rv;
+ if (rv < iov[i].iov_len)
break;
- else
- {
- total += rv;
- if (rv < iov[i].iov_len)
- {
- if (LDP_DEBUG > 4)
- printf ("%s:%d: LDP<%d>: fd %d (0x%x): "
- "rv (%d) < iov[%d].iov_len (%ld)",
- __func__, __LINE__, getpid (), fd, fd,
- rv, i, iov[i].iov_len);
- break;
- }
- }
}
}
- while ((rv >= 0) && (total == 0));
- if (rv < 0)
+ if (rv < 0 && total == 0)
{
errno = -rv;
size = -1;
}
else
{
- func_str = "libc_writev";
-
- if (LDP_DEBUG > 4)
- printf ("%s:%d: LDP<%d>: fd %d (0x%x): calling %s(): "
- "iov %p, iovcnt %d\n", __func__, __LINE__, getpid (),
- fd, fd, func_str, iov, iovcnt);
-
size = libc_writev (fd, iov, iovcnt);
}
- if (LDP_DEBUG > 4)
- {
- if (size < 0)
- {
- int errno_val = errno;
- perror (func_str);
- fprintf (stderr,
- "%s:%d: LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %ld, errno = %d\n", __func__, __LINE__, getpid (), fd,
- fd, func_str, size, errno_val);
- errno = errno_val;
- }
- else
- printf ("%s:%d: LDP<%d>: fd %d (0x%x): returning %ld\n",
- __func__, __LINE__, getpid (), fd, fd, size);
- }
return size;
}
-int
-fcntl (int fd, int cmd, ...)
+static int
+fcntl_internal (int fd, int cmd, va_list ap)
{
- const char *func_str = __func__;
+ vls_handle_t vlsh;
int rv = 0;
- va_list ap;
- u32 sid = ldp_sid_from_fd (fd);
-
- if ((errno = -ldp_init ()))
- return -1;
- va_start (ap, cmd);
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ LDBG (0, "fd %u vlsh %d, cmd %u", fd, vlsh, cmd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
int flags = va_arg (ap, int);
u32 size;
switch (cmd)
{
case F_SETFL:
- func_str = "vppcom_session_attr[SET_FLAGS]";
- LDBG (2, "fd %d (0x%x): calling %s(): sid %u (0x%x) "
- "flags %d (0x%x), size %d", fd, fd, func_str, sid,
- sid, flags, flags, size);
-
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
- &size);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
break;
case F_GETFL:
- func_str = "vppcom_session_attr[GET_FLAGS]";
- LDBG (2, "fd %d (0x%x): calling %s(): sid %u (0x%x), "
- "flags %d (0x%x), size %d", fd, fd, func_str, sid,
- sid, flags, flags, size);
-
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
- &size);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_FLAGS, &flags, &size);
if (rv == VPPCOM_OK)
- {
- LDBG (2, "fd %d (0x%x), cmd %d (F_GETFL): %s() "
- "returned flags %d (0x%x)", fd, fd, cmd,
- func_str, flags, flags);
- rv = flags;
- }
+ rv = flags;
break;
case F_SETFD:
/* TODO handle this */
}
else
{
- func_str = "libc_vfcntl";
-
- LDBG (2, "fd %d (0x%x): calling %s(): cmd %d", fd, fd, func_str, cmd);
-
+#ifdef HAVE_FCNTL64
+ rv = libc_vfcntl64 (fd, cmd, ap);
+#else
rv = libc_vfcntl (fd, cmd, ap);
+#endif
}
+ return rv;
+}
+
+int
+fcntl (int fd, int cmd, ...)
+{
+ va_list ap;
+ int rv;
+
+ ldp_init_check ();
+
+ va_start (ap, cmd);
+ rv = fcntl_internal (fd, cmd, ap);
va_end (ap);
- if (LDP_DEBUG > 2)
- {
- if (rv < 0)
- {
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), fd, fd,
- func_str, rv, errno_val);
- errno = errno_val;
- }
- else
- clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
- getpid (), fd, fd, rv, rv);
- }
return rv;
}
int
-ioctl (int fd, unsigned long int cmd, ...)
+fcntl64 (int fd, int cmd, ...)
{
- const char *func_str;
+ va_list ap;
int rv;
+
+ ldp_init_check ();
+
+ va_start (ap, cmd);
+ rv = fcntl_internal (fd, cmd, ap);
+ va_end (ap);
+ return rv;
+}
+
+int
+ioctl (int fd, unsigned long int cmd, ...)
+{
+ vls_handle_t vlsh;
va_list ap;
- u32 sid = ldp_sid_from_fd (fd);
+ int rv;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
va_start (ap, cmd);
- if (sid != INVALID_SESSION_ID)
- {
- func_str = "vppcom_session_attr[GET_NREAD]";
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
+ {
switch (cmd)
{
case FIONREAD:
- if (LDP_DEBUG > 2)
- clib_warning
- ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
-
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NREAD, 0, 0);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_NREAD, 0, 0);
break;
case FIONBIO:
{
- u32 flags = va_arg (ap, int) ? O_NONBLOCK : 0;
+ u32 flags = *(va_arg (ap, int *)) ? O_NONBLOCK : 0;
u32 size = sizeof (flags);
/* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than
* non-blocking, the flags should be read here and merged
* with O_NONBLOCK.
*/
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x), flags %d (0x%x), size %d",
- getpid (), fd, fd, func_str, sid, sid,
- flags, flags, size);
-
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
- &size);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
}
break;
}
else
{
- func_str = "libc_vioctl";
-
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
- getpid (), fd, fd, func_str, cmd);
-
rv = libc_vioctl (fd, cmd, ap);
}
- if (LDP_DEBUG > 2)
- {
- if (rv < 0)
- {
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), fd, fd,
- func_str, rv, errno_val);
- errno = errno_val;
- }
- else
- clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
- getpid (), fd, fd, rv, rv);
- }
va_end (ap);
return rv;
}
+always_inline void
+ldp_select_init_maps (fd_set * __restrict original,
+ clib_bitmap_t ** resultb, clib_bitmap_t ** libcb,
+ clib_bitmap_t ** vclb, int nfds, u32 minbits,
+ u32 n_bytes, uword * si_bits, uword * libc_bits)
+{
+ uword si_bits_set, libc_bits_set;
+ vls_handle_t vlsh;
+ int fd;
+
+ clib_bitmap_validate (*vclb, minbits);
+ clib_bitmap_validate (*libcb, minbits);
+ clib_bitmap_validate (*resultb, minbits);
+ clib_memcpy_fast (*resultb, original, n_bytes);
+ memset (original, 0, n_bytes);
+
+ /* *INDENT-OFF* */
+ clib_bitmap_foreach (fd, *resultb) {
+ if (fd > nfds)
+ break;
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh == VLS_INVALID_HANDLE)
+ clib_bitmap_set_no_check (*libcb, fd, 1);
+ else
+ *vclb = clib_bitmap_set (*vclb, vlsh_to_session_index (vlsh), 1);
+ }
+ /* *INDENT-ON* */
+
+ si_bits_set = clib_bitmap_last_set (*vclb) + 1;
+ *si_bits = (si_bits_set > *si_bits) ? si_bits_set : *si_bits;
+ clib_bitmap_validate (*resultb, *si_bits);
+
+ libc_bits_set = clib_bitmap_last_set (*libcb) + 1;
+ *libc_bits = (libc_bits_set > *libc_bits) ? libc_bits_set : *libc_bits;
+}
+
+always_inline int
+ldp_select_vcl_map_to_libc (clib_bitmap_t * vclb, fd_set * __restrict libcb)
+{
+ vls_handle_t vlsh;
+ uword si;
+ int fd;
+
+ if (!libcb)
+ return 0;
+
+ /* *INDENT-OFF* */
+ clib_bitmap_foreach (si, vclb) {
+ vlsh = vls_session_index_to_vlsh (si);
+ ASSERT (vlsh != VLS_INVALID_HANDLE);
+ fd = ldp_vlsh_to_fd (vlsh);
+ if (PREDICT_FALSE (fd < 0))
+ {
+ errno = EBADFD;
+ return -1;
+ }
+ FD_SET (fd, libcb);
+ }
+ /* *INDENT-ON* */
+
+ return 0;
+}
+
+always_inline void
+ldp_select_libc_map_merge (clib_bitmap_t * result, fd_set * __restrict libcb)
+{
+ uword fd;
+
+ if (!libcb)
+ return;
+
+ /* *INDENT-OFF* */
+ clib_bitmap_foreach (fd, result)
+ FD_SET ((int)fd, libcb);
+ /* *INDENT-ON* */
+}
+
int
ldp_pselect (int nfds, fd_set * __restrict readfds,
fd_set * __restrict writefds,
const struct timespec *__restrict timeout,
const __sigset_t * __restrict sigmask)
{
- uword sid_bits, sid_bits_set, libc_bits, libc_bits_set;
+ u32 minbits = clib_max (nfds, BITS (uword)), n_bytes;
ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
- u32 minbits = clib_max (nfds, BITS (uword)), sid;
- char *func_str = "##";
- f64 time_out;
- int rv, fd;
+ struct timespec libc_tspec = { 0 };
+ f64 time_out, vcl_timeout = 0;
+ uword si_bits, libc_bits;
+ int rv, bits_set = 0;
if (nfds < 0)
{
return -1;
}
+ if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
+ clib_time_init (&ldpw->clib_time);
+
if (timeout)
{
time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
- (f64) 0 : (f64) timeout->tv_sec +
- (f64) timeout->tv_nsec / (f64) 1000000000;
+ (f64) 0 : (f64) timeout->tv_sec + (f64) timeout->tv_nsec / (f64) 1e9;
+
+ time_out += clib_time_now (&ldpw->clib_time);
/* select as fine grained sleep */
if (!nfds)
{
- LDBG (3, "sleeping for %.02f seconds", time_out);
-
- time_out += clib_time_now (&ldpw->clib_time);
while (clib_time_now (&ldpw->clib_time) < time_out)
;
return 0;
else
time_out = -1;
-
- if (nfds <= ldp->sid_bit_val)
+ if (nfds <= ldp->vlsh_bit_val)
{
- func_str = "libc_pselect";
-
- LDBG (3, "calling %s(): nfds %d, readfds %p, writefds %p, "
- "exceptfds %p, timeout %p, sigmask %p", func_str, nfds,
- readfds, writefds, exceptfds, timeout, sigmask);
-
rv = libc_pselect (nfds, readfds, writefds, exceptfds,
timeout, sigmask);
goto done;
}
- if (PREDICT_FALSE (ldp->sid_bit_val > FD_SETSIZE / 2))
- {
- clib_warning ("LDP<%d>: ERROR: LDP sid bit value %d (0x%x) > "
- "FD_SETSIZE/2 %d (0x%x)!", getpid (),
- ldp->sid_bit_val, ldp->sid_bit_val,
- FD_SETSIZE / 2, FD_SETSIZE / 2);
- errno = EOVERFLOW;
- return -1;
- }
+ si_bits = libc_bits = 0;
+ n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0);
- sid_bits = libc_bits = 0;
- u32 n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0);
if (readfds)
- {
- clib_bitmap_validate (ldpw->sid_rd_bitmap, minbits);
- clib_bitmap_validate (ldpw->libc_rd_bitmap, minbits);
- clib_bitmap_validate (ldpw->rd_bitmap, minbits);
- clib_memcpy_fast (ldpw->rd_bitmap, readfds, n_bytes);
- memset (readfds, 0, n_bytes);
-
- /* *INDENT-OFF* */
- clib_bitmap_foreach (fd, ldpw->rd_bitmap, ({
- if (fd > nfds)
- break;
- sid = ldp_sid_from_fd (fd);
- LDBG (3, "readfds: fd %d (0x%x), sid %u (0x%x)", fd, fd, sid, sid);
- if (sid == INVALID_SESSION_ID)
- clib_bitmap_set_no_check (ldpw->libc_rd_bitmap, fd, 1);
- else
- clib_bitmap_set_no_check (ldpw->sid_rd_bitmap,
- vppcom_session_index (sid), 1);
- }));
- /* *INDENT-ON* */
-
- sid_bits_set = clib_bitmap_last_set (ldpw->sid_rd_bitmap) + 1;
- sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
-
- libc_bits_set = clib_bitmap_last_set (ldpw->libc_rd_bitmap) + 1;
- libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
-
- LDBG (3, "readfds: sid_bits_set %d, sid_bits %d, "
- "libc_bits_set %d, libc_bits %d", sid_bits_set,
- sid_bits, libc_bits_set, libc_bits);
- }
+ ldp_select_init_maps (readfds, &ldpw->rd_bitmap, &ldpw->libc_rd_bitmap,
+ &ldpw->si_rd_bitmap, nfds, minbits, n_bytes,
+ &si_bits, &libc_bits);
if (writefds)
- {
- clib_bitmap_validate (ldpw->sid_wr_bitmap, minbits);
- clib_bitmap_validate (ldpw->libc_wr_bitmap, minbits);
- clib_bitmap_validate (ldpw->wr_bitmap, minbits);
- clib_memcpy_fast (ldpw->wr_bitmap, writefds, n_bytes);
- memset (writefds, 0, n_bytes);
-
- /* *INDENT-OFF* */
- clib_bitmap_foreach (fd, ldpw->wr_bitmap, ({
- if (fd > nfds)
- break;
- sid = ldp_sid_from_fd (fd);
- LDBG (3, "writefds: fd %d (0x%x), sid %u (0x%x)", fd, fd, sid, sid);
- if (sid == INVALID_SESSION_ID)
- clib_bitmap_set_no_check (ldpw->libc_wr_bitmap, fd, 1);
- else
- clib_bitmap_set_no_check (ldpw->sid_wr_bitmap,
- vppcom_session_index (sid), 1);
- }));
- /* *INDENT-ON* */
-
- sid_bits_set = clib_bitmap_last_set (ldpw->sid_wr_bitmap) + 1;
- sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
-
- libc_bits_set = clib_bitmap_last_set (ldpw->libc_wr_bitmap) + 1;
- libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
-
- LDBG (3, "writefds: sid_bits_set %d, sid_bits %d, "
- "libc_bits_set %d, libc_bits %d",
- sid_bits_set, sid_bits, libc_bits_set, libc_bits);
- }
+ ldp_select_init_maps (writefds, &ldpw->wr_bitmap,
+ &ldpw->libc_wr_bitmap, &ldpw->si_wr_bitmap, nfds,
+ minbits, n_bytes, &si_bits, &libc_bits);
if (exceptfds)
- {
- clib_bitmap_validate (ldpw->sid_ex_bitmap, minbits);
- clib_bitmap_validate (ldpw->libc_ex_bitmap, minbits);
- clib_bitmap_validate (ldpw->ex_bitmap, minbits);
- clib_memcpy_fast (ldpw->ex_bitmap, exceptfds, n_bytes);
- memset (exceptfds, 0, n_bytes);
-
- /* *INDENT-OFF* */
- clib_bitmap_foreach (fd, ldpw->ex_bitmap, ({
- if (fd > nfds)
- break;
- sid = ldp_sid_from_fd (fd);
- LDBG (3, "exceptfds: fd %d (0x%x), sid %u (0x%x)", fd, fd, sid, sid);
- if (sid == INVALID_SESSION_ID)
- clib_bitmap_set_no_check (ldpw->libc_ex_bitmap, fd, 1);
- else
- clib_bitmap_set_no_check (ldpw->sid_ex_bitmap,
- vppcom_session_index (sid), 1);
- }));
- /* *INDENT-ON* */
-
- sid_bits_set = clib_bitmap_last_set (ldpw->sid_ex_bitmap) + 1;
- sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
+ ldp_select_init_maps (exceptfds, &ldpw->ex_bitmap,
+ &ldpw->libc_ex_bitmap, &ldpw->si_ex_bitmap, nfds,
+ minbits, n_bytes, &si_bits, &libc_bits);
- libc_bits_set = clib_bitmap_last_set (ldpw->libc_ex_bitmap) + 1;
- libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
-
- LDBG (3, "exceptfds: sid_bits_set %d, sid_bits %d, "
- "libc_bits_set %d, libc_bits %d",
- sid_bits_set, sid_bits, libc_bits_set, libc_bits);
- }
-
- if (PREDICT_FALSE (!sid_bits && !libc_bits))
+ if (PREDICT_FALSE (!si_bits && !libc_bits))
{
errno = EINVAL;
rv = -1;
goto done;
}
+ if (!si_bits)
+ libc_tspec = timeout ? *timeout : libc_tspec;
+
do
{
- if (sid_bits)
+ if (si_bits)
{
- if (!ldpw->select_vcl)
+ if (readfds)
+ clib_memcpy_fast (ldpw->rd_bitmap, ldpw->si_rd_bitmap,
+ vec_len (ldpw->si_rd_bitmap) *
+ sizeof (clib_bitmap_t));
+ if (writefds)
+ clib_memcpy_fast (ldpw->wr_bitmap, ldpw->si_wr_bitmap,
+ vec_len (ldpw->si_wr_bitmap) *
+ sizeof (clib_bitmap_t));
+ if (exceptfds)
+ clib_memcpy_fast (ldpw->ex_bitmap, ldpw->si_ex_bitmap,
+ vec_len (ldpw->si_ex_bitmap) *
+ sizeof (clib_bitmap_t));
+
+ rv = vls_select (si_bits, readfds ? ldpw->rd_bitmap : NULL,
+ writefds ? ldpw->wr_bitmap : NULL,
+ exceptfds ? ldpw->ex_bitmap : NULL, vcl_timeout);
+ if (rv < 0)
+ {
+ errno = -rv;
+ rv = -1;
+ goto done;
+ }
+ else if (rv > 0)
{
- func_str = "vppcom_select";
-
- if (readfds)
- clib_memcpy_fast (ldpw->rd_bitmap, ldpw->sid_rd_bitmap,
- vec_len (ldpw->rd_bitmap) *
- sizeof (clib_bitmap_t));
- if (writefds)
- clib_memcpy_fast (ldpw->wr_bitmap, ldpw->sid_wr_bitmap,
- vec_len (ldpw->wr_bitmap) *
- sizeof (clib_bitmap_t));
- if (exceptfds)
- clib_memcpy_fast (ldpw->ex_bitmap, ldpw->sid_ex_bitmap,
- vec_len (ldpw->ex_bitmap) *
- sizeof (clib_bitmap_t));
-
- rv = vppcom_select (sid_bits,
- readfds ? ldpw->rd_bitmap : NULL,
- writefds ? ldpw->wr_bitmap : NULL,
- exceptfds ? ldpw->ex_bitmap : NULL, 0);
- if (rv < 0)
+ if (ldp_select_vcl_map_to_libc (ldpw->rd_bitmap, readfds))
{
- errno = -rv;
rv = -1;
+ goto done;
}
- else if (rv > 0)
+
+ if (ldp_select_vcl_map_to_libc (ldpw->wr_bitmap, writefds))
{
- if (readfds)
- {
- /* *INDENT-OFF* */
- clib_bitmap_foreach (sid, ldpw->rd_bitmap,
- ({
- fd = ldp_fd_from_sid (vppcom_session_handle (sid));
- if (PREDICT_FALSE (fd < 0))
- {
- errno = EBADFD;
- rv = -1;
- goto done;
- }
- FD_SET (fd, readfds);
- }));
- /* *INDENT-ON* */
- }
- if (writefds)
- {
- /* *INDENT-OFF* */
- clib_bitmap_foreach (sid, ldpw->wr_bitmap,
- ({
- fd = ldp_fd_from_sid (vppcom_session_handle (sid));
- if (PREDICT_FALSE (fd < 0))
- {
- errno = EBADFD;
- rv = -1;
- goto done;
- }
- FD_SET (fd, writefds);
- }));
- /* *INDENT-ON* */
- }
- if (exceptfds)
- {
- /* *INDENT-OFF* */
- clib_bitmap_foreach (sid, ldpw->ex_bitmap,
- ({
- fd = ldp_fd_from_sid (vppcom_session_handle (sid));
- if (PREDICT_FALSE (fd < 0))
- {
- errno = EBADFD;
- rv = -1;
- goto done;
- }
- FD_SET (fd, exceptfds);
- }));
- /* *INDENT-ON* */
- }
- ldpw->select_vcl = 1;
+ rv = -1;
+ goto done;
+ }
+
+ if (ldp_select_vcl_map_to_libc (ldpw->ex_bitmap, exceptfds))
+ {
+ rv = -1;
goto done;
}
+ bits_set = rv;
}
- else
- ldpw->select_vcl = 0;
}
if (libc_bits)
{
- struct timespec tspec;
-
- func_str = "libc_pselect";
-
if (readfds)
- clib_memcpy_fast (readfds, ldpw->libc_rd_bitmap,
- vec_len (ldpw->rd_bitmap) *
+ clib_memcpy_fast (ldpw->rd_bitmap, ldpw->libc_rd_bitmap,
+ vec_len (ldpw->libc_rd_bitmap) *
sizeof (clib_bitmap_t));
if (writefds)
- clib_memcpy_fast (writefds, ldpw->libc_wr_bitmap,
- vec_len (ldpw->wr_bitmap) *
+ clib_memcpy_fast (ldpw->wr_bitmap, ldpw->libc_wr_bitmap,
+ vec_len (ldpw->libc_wr_bitmap) *
sizeof (clib_bitmap_t));
if (exceptfds)
- clib_memcpy_fast (exceptfds, ldpw->libc_ex_bitmap,
- vec_len (ldpw->ex_bitmap) *
+ clib_memcpy_fast (ldpw->ex_bitmap, ldpw->libc_ex_bitmap,
+ vec_len (ldpw->libc_ex_bitmap) *
sizeof (clib_bitmap_t));
- tspec.tv_sec = tspec.tv_nsec = 0;
+
rv = libc_pselect (libc_bits,
- readfds ? readfds : NULL,
- writefds ? writefds : NULL,
- exceptfds ? exceptfds : NULL, &tspec, sigmask);
- if (rv != 0)
- goto done;
+ readfds ? (fd_set *) ldpw->rd_bitmap : NULL,
+ writefds ? (fd_set *) ldpw->wr_bitmap : NULL,
+ exceptfds ? (fd_set *) ldpw->ex_bitmap : NULL,
+ &libc_tspec, sigmask);
+ if (rv > 0)
+ {
+ ldp_select_libc_map_merge (ldpw->rd_bitmap, readfds);
+ ldp_select_libc_map_merge (ldpw->wr_bitmap, writefds);
+ ldp_select_libc_map_merge (ldpw->ex_bitmap, exceptfds);
+ bits_set += rv;
+ }
+ }
+
+ if (bits_set)
+ {
+ rv = bits_set;
+ goto done;
}
}
while ((time_out == -1) || (clib_time_now (&ldpw->clib_time) < time_out));
done:
/* TBD: set timeout to amount of time left */
clib_bitmap_zero (ldpw->rd_bitmap);
- clib_bitmap_zero (ldpw->sid_rd_bitmap);
+ clib_bitmap_zero (ldpw->si_rd_bitmap);
clib_bitmap_zero (ldpw->libc_rd_bitmap);
clib_bitmap_zero (ldpw->wr_bitmap);
- clib_bitmap_zero (ldpw->sid_wr_bitmap);
+ clib_bitmap_zero (ldpw->si_wr_bitmap);
clib_bitmap_zero (ldpw->libc_wr_bitmap);
clib_bitmap_zero (ldpw->ex_bitmap);
- clib_bitmap_zero (ldpw->sid_ex_bitmap);
+ clib_bitmap_zero (ldpw->si_ex_bitmap);
clib_bitmap_zero (ldpw->libc_ex_bitmap);
- if (LDP_DEBUG > 3)
- {
- if (rv < 0)
- {
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: %s() failed! "
- "rv %d, errno = %d", getpid (),
- func_str, rv, errno_val);
- errno = errno_val;
- }
- else
- clib_warning ("LDP<%d>: returning %d (0x%x)", getpid (), rv, rv);
- }
return rv;
}
}
#endif
+/* If transparent TLS mode is turned on, then ldp will load key and cert.
+ */
+static int
+load_cert_key_pair (void)
+{
+ char *cert_str = getenv (LDP_ENV_TLS_CERT);
+ char *key_str = getenv (LDP_ENV_TLS_KEY);
+ char cert_buf[4096], key_buf[4096];
+ int cert_size, key_size;
+ vppcom_cert_key_pair_t crypto;
+ int ckp_index;
+ FILE *fp;
+
+ if (!cert_str || !key_str)
+ {
+ LDBG (0, "ERROR: failed to read LDP environment %s\n",
+ LDP_ENV_TLS_CERT);
+ return -1;
+ }
+
+ fp = fopen (cert_str, "r");
+ if (fp == NULL)
+ {
+ LDBG (0, "ERROR: failed to open cert file %s \n", cert_str);
+ return -1;
+ }
+ cert_size = fread (cert_buf, sizeof (char), sizeof (cert_buf), fp);
+ fclose (fp);
+
+ fp = fopen (key_str, "r");
+ if (fp == NULL)
+ {
+ LDBG (0, "ERROR: failed to open key file %s \n", key_str);
+ return -1;
+ }
+ key_size = fread (key_buf, sizeof (char), sizeof (key_buf), fp);
+ fclose (fp);
+
+ crypto.cert = cert_buf;
+ crypto.key = key_buf;
+ crypto.cert_len = cert_size;
+ crypto.key_len = key_size;
+ ckp_index = vppcom_add_cert_key_pair (&crypto);
+ if (ckp_index < 0)
+ {
+ LDBG (0, "ERROR: failed to add cert key pair\n");
+ return -1;
+ }
+
+ ldp->ckpair_index = ckp_index;
+
+ return 0;
+}
+
+static int
+assign_cert_key_pair (vls_handle_t vlsh)
+{
+ uint32_t ckp_len;
+
+ if (ldp->ckpair_index == ~0 && load_cert_key_pair () < 0)
+ return -1;
+
+ ckp_len = sizeof (ldp->ckpair_index);
+ return vls_attr (vlsh, VPPCOM_ATTR_SET_CKPAIR, &ldp->ckpair_index, &ckp_len);
+}
+
int
socket (int domain, int type, int protocol)
{
- const char *func_str;
- int rv;
+ int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
- int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
+ vls_handle_t vlsh;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
if (((domain == AF_INET) || (domain == AF_INET6)) &&
((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
{
- int sid;
- u8 proto = ((sock_type == SOCK_DGRAM) ?
- VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
-
- func_str = "vppcom_session_create";
+ u8 proto;
+ if (ldp->transparent_tls)
+ {
+ proto = VPPCOM_PROTO_TLS;
+ }
+ else
+ proto = ((sock_type == SOCK_DGRAM) ?
+ VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
- LDBG (0, "calling %s(): proto %u (%s), is_nonblocking %u",
- func_str, proto, vppcom_proto_str (proto), is_nonblocking);
+ LDBG (0, "calling vls_create: proto %u (%s), is_nonblocking %u",
+ proto, vppcom_proto_str (proto), is_nonblocking);
- sid = vppcom_session_create (proto, is_nonblocking);
- if (sid < 0)
+ vlsh = vls_create (proto, is_nonblocking);
+ if (vlsh < 0)
{
- errno = -sid;
+ errno = -vlsh;
rv = -1;
}
else
{
- func_str = "ldp_fd_from_sid";
- rv = ldp_fd_alloc (sid);
- if (rv < 0)
+ if (ldp->transparent_tls)
{
- (void) vppcom_session_close (sid);
- errno = -rv;
- rv = -1;
+ if (assign_cert_key_pair (vlsh) < 0)
+ return -1;
}
+ rv = ldp_vlsh_to_fd (vlsh);
}
}
else
{
- func_str = "libc_socket";
-
- LDBG (0, "calling %s()", func_str);
-
+ LDBG (0, "calling libc_socket");
rv = libc_socket (domain, type, protocol);
}
- if (LDP_DEBUG > 0)
- {
- if (rv < 0)
- {
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: %s() failed! "
- "rv %d, errno = %d",
- getpid (), func_str, rv, errno_val);
- errno = errno_val;
- }
- else
- clib_warning ("returning fd %d (0x%x)", getpid (), rv, rv);
- }
return rv;
}
int
socketpair (int domain, int type, int protocol, int fds[2])
{
- const char *func_str;
- int rv;
- int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
+ int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
if (((domain == AF_INET) || (domain == AF_INET6)) &&
((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
{
- func_str = __func__;
-
- clib_warning ("LDP<%d>: LDP-TBD", getpid ());
+ LDBG (0, "LDP-TBD");
errno = ENOSYS;
rv = -1;
}
else
{
- func_str = "libc_socket";
-
- LDBG (1, "calling %s()", func_str);
-
+ LDBG (1, "calling libc_socketpair");
rv = libc_socketpair (domain, type, protocol, fds);
}
- if (LDP_DEBUG > 1)
- {
- if (rv < 0)
- {
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: %s() failed! "
- "rv %d, errno = %d",
- getpid (), func_str, rv, errno_val);
- errno = errno_val;
- }
- else
- clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
- }
return rv;
}
int
-bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
+bind (int fd, __CONST_SOCKADDR_ARG _addr, socklen_t len)
{
+ const struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
+ vls_handle_t vlsh;
int rv;
- u32 sid = ldp_sid_from_fd (fd);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
vppcom_endpt_t ep;
case AF_INET:
if (len != sizeof (struct sockaddr_in))
{
- clib_warning
- ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
- "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
+ LDBG (0, "ERROR: fd %d: vlsh %u: Invalid AF_INET addr len %u!",
+ fd, vlsh, len);
errno = EINVAL;
rv = -1;
goto done;
case AF_INET6:
if (len != sizeof (struct sockaddr_in6))
{
- clib_warning
- ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
- "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
+ LDBG (0, "ERROR: fd %d: vlsh %u: Invalid AF_INET6 addr len %u!",
+ fd, vlsh, len);
errno = EINVAL;
rv = -1;
goto done;
break;
default:
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): "
- "Unsupported address family %u!",
- getpid (), fd, fd, sid, sid, addr->sa_family);
+ LDBG (0, "ERROR: fd %d: vlsh %u: Unsupported address family %u!",
+ fd, vlsh, addr->sa_family);
errno = EAFNOSUPPORT;
rv = -1;
goto done;
}
- LDBG (0, "fd %d (0x%x): calling vppcom_session_bind(): "
- "sid %u (0x%x), addr %p, len %u", fd, fd, sid, sid, addr, len);
+ LDBG (0, "fd %d: calling vls_bind: vlsh %u, addr %p, len %u", fd, vlsh,
+ addr, len);
- rv = vppcom_session_bind (sid, &ep);
+ rv = vls_bind (vlsh, &ep);
if (rv != VPPCOM_OK)
{
errno = -rv;
}
else
{
- LDBG (0, "fd %d (0x%x): calling libc_bind(): addr %p, len %u",
- fd, fd, addr, len);
-
+ LDBG (0, "fd %d: calling libc_bind: addr %p, len %u", fd, addr, len);
rv = libc_bind (fd, addr, len);
}
done:
- LDBG (1, "fd %d (0x%x): returning %d", fd, fd, rv);
+ LDBG (1, "fd %d: returning %d", fd, rv);
return rv;
}
static inline int
-ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
- vppcom_endpt_t * ep)
+ldp_copy_ep_to_sockaddr (struct sockaddr *addr, socklen_t *__restrict len,
+ vppcom_endpt_t *ep)
{
- int rv = 0;
- int sa_len, copy_len;
+ int rv = 0, sa_len, copy_len;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
if (addr && len && ep)
{
}
int
-getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
+getsockname (int fd, __SOCKADDR_ARG _addr, socklen_t *__restrict len)
{
+ struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
+ vls_handle_t vlsh;
int rv;
- const char *func_str;
- u32 sid = ldp_sid_from_fd (fd);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
vppcom_endpt_t ep;
u8 addr_buf[sizeof (struct in6_addr)];
u32 size = sizeof (ep);
ep.ip = addr_buf;
- func_str = "vppcom_session_attr[GET_LCL_ADDR]";
-
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
- "addr %p, len %u",
- getpid (), fd, fd, func_str, sid, sid, addr, len);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
if (rv != VPPCOM_OK)
{
errno = -rv;
}
else
{
- func_str = "libc_getsockname";
-
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "addr %p, len %u",
- getpid (), fd, fd, func_str, addr, len);
-
- rv = libc_getsockname (fd, addr, len);
+ rv = libc_getsockname (fd, _addr, len);
}
- if (LDP_DEBUG > 2)
- {
- if (rv < 0)
- {
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), fd, fd,
- func_str, rv, errno_val);
- errno = errno_val;
- }
- else
- clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
- getpid (), fd, fd, rv, rv);
- }
return rv;
}
int
-connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
+connect (int fd, __CONST_SOCKADDR_ARG _addr, socklen_t len)
{
+ const struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
+ vls_handle_t vlsh;
int rv;
- u32 sid = ldp_sid_from_fd (fd);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
if (!addr)
{
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): NULL addr, len %u",
- getpid (), fd, fd, len);
+ LDBG (0, "ERROR: fd %d: NULL addr, len %u", fd, len);
errno = EINVAL;
rv = -1;
goto done;
}
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
vppcom_endpt_t ep;
case AF_INET:
if (len != sizeof (struct sockaddr_in))
{
- clib_warning
- ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
- "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
+ LDBG (0, "fd %d: ERROR vlsh %u: Invalid AF_INET addr len %u!",
+ fd, vlsh, len);
errno = EINVAL;
rv = -1;
goto done;
case AF_INET6:
if (len != sizeof (struct sockaddr_in6))
{
- clib_warning
- ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
- "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
+ LDBG (0, "fd %d: ERROR vlsh %u: Invalid AF_INET6 addr len %u!",
+ fd, vlsh, len);
errno = EINVAL;
rv = -1;
goto done;
break;
default:
- clib_warning ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): "
- "Unsupported address family %u!",
- getpid (), fd, fd, sid, sid, addr->sa_family);
+ LDBG (0, "fd %d: ERROR vlsh %u: Unsupported address family %u!",
+ fd, vlsh, addr->sa_family);
errno = EAFNOSUPPORT;
rv = -1;
goto done;
}
- LDBG (0, "fd %d (0x%x): calling vppcom_session_connect(): sid %u (0x%x)"
- " addr %p len %u", fd, fd, sid, sid, addr, len);
+ LDBG (0, "fd %d: calling vls_connect(): vlsh %u addr %p len %u", fd,
+ vlsh, addr, len);
- rv = vppcom_session_connect (sid, &ep);
+ rv = vls_connect (vlsh, &ep);
if (rv != VPPCOM_OK)
{
errno = -rv;
}
else
{
- LDBG (0, "fd %d (0x%x): calling libc_connect(): addr %p, len %u",
- fd, fd, addr, len);
+ LDBG (0, "fd %d: calling libc_connect(): addr %p, len %u",
+ fd, addr, len);
rv = libc_connect (fd, addr, len);
}
done:
- LDBG (1, "fd %d (0x%x): returning %d (0x%x)", fd, fd, rv, rv);
+ LDBG (1, "fd %d: returning %d (0x%x)", fd, rv, rv);
return rv;
}
int
-getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
+getpeername (int fd, __SOCKADDR_ARG _addr, socklen_t *__restrict len)
{
+ struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
+ vls_handle_t vlsh;
int rv;
- const char *func_str;
- u32 sid = ldp_sid_from_fd (fd);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
vppcom_endpt_t ep;
u8 addr_buf[sizeof (struct in6_addr)];
u32 size = sizeof (ep);
ep.ip = addr_buf;
- func_str = "vppcom_session_attr[GET_PEER_ADDR]";
-
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
- "addr %p, len %u",
- getpid (), fd, fd, func_str, sid, sid, addr, len);
-
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
if (rv != VPPCOM_OK)
{
errno = -rv;
}
else
{
- func_str = "libc_getpeername";
-
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "addr %p, len %u",
- getpid (), fd, fd, func_str, addr, len);
-
rv = libc_getpeername (fd, addr, len);
}
- if (LDP_DEBUG > 2)
- {
- if (rv < 0)
- {
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), fd, fd,
- func_str, rv, errno_val);
- errno = errno_val;
- }
- else
- clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
- getpid (), fd, fd, rv, rv);
- }
return rv;
}
ssize_t
send (int fd, const void *buf, size_t n, int flags)
{
+ vls_handle_t vlsh = ldp_fd_to_vlsh (fd);
ssize_t size;
- const char *func_str;
- u32 sid = ldp_sid_from_fd (fd);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ if (vlsh != VLS_INVALID_HANDLE)
{
-
- func_str = "vppcom_session_sendto";
-
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
- "buf %p, n %u, flags 0x%x",
- getpid (), fd, fd, func_str, sid, sid, buf, n, flags);
-
- size = vppcom_session_sendto (sid, (void *) buf, n, flags, NULL);
+ size = vls_sendto (vlsh, (void *) buf, n, flags, NULL);
if (size < VPPCOM_OK)
{
errno = -size;
}
else
{
- func_str = "libc_send";
-
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "buf %p, n %u, flags 0x%x",
- getpid (), fd, fd, func_str, buf, n, flags);
-
size = libc_send (fd, buf, n, flags);
}
- if (LDP_DEBUG > 2)
- {
- if (size < 0)
- {
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), fd, fd,
- func_str, size, errno_val);
- errno = errno_val;
- }
- else
- clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
- getpid (), fd, fd, size, size);
- }
return size;
}
sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
{
ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
+ vls_handle_t vlsh;
ssize_t size = 0;
- const char *func_str;
- u32 sid = ldp_sid_from_fd (out_fd);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (out_fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
int rv;
ssize_t results = 0;
size_t n_bytes_left = len;
size_t bytes_to_read;
int nbytes;
- int errno_val;
u8 eagain = 0;
u32 flags, flags_len = sizeof (flags);
- func_str = "vppcom_session_attr[GET_FLAGS]";
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
- &flags_len);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_FLAGS, &flags, &flags_len);
if (PREDICT_FALSE (rv != VPPCOM_OK))
{
- clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
- "sid %u (0x%x), returned %d (%s)!", getpid (),
- out_fd, out_fd, func_str, sid, sid, rv,
- vppcom_retval_str (rv));
+ LDBG (0, "ERROR: out fd %d: vls_attr: vlsh %u, returned %d (%s)!",
+ out_fd, vlsh, rv, vppcom_retval_str (rv));
vec_reset_length (ldpw->io_buffer);
errno = -rv;
off_t off = lseek (in_fd, *offset, SEEK_SET);
if (PREDICT_FALSE (off == -1))
{
- func_str = "lseek";
- errno_val = errno;
- clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
- "SEEK_SET failed: in_fd %d, offset %p, "
- "*offset %ld, rv %ld, errno %d", getpid (),
- out_fd, out_fd, in_fd, offset, *offset, off,
- errno_val);
- errno = errno_val;
size = -1;
goto done;
}
do
{
- func_str = "vppcom_session_attr[GET_NWRITE]";
- size = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NWRITE, 0, 0);
+ size = vls_attr (vlsh, VPPCOM_ATTR_GET_NWRITE, 0, 0);
if (size < 0)
{
- clib_warning
- ("LDP<%d>: ERROR: fd %d (0x%x): %s(): sid %u (0x%x), "
- "returned %d (%s)!", getpid (), out_fd, out_fd, func_str,
- sid, sid, size, vppcom_retval_str (size));
+ LDBG (0, "ERROR: fd %d: vls_attr: vlsh %u returned %ld (%s)!",
+ out_fd, vlsh, size, vppcom_retval_str (size));
vec_reset_length (ldpw->io_buffer);
errno = -size;
size = -1;
}
bytes_to_read = size;
- if (LDP_DEBUG > 2)
- clib_warning
- ("LDP<%d>: fd %d (0x%x): called %s(): sid %u (0x%x), "
- "results %ld, n_bytes_left %lu, bytes_to_read %lu", getpid (),
- out_fd, out_fd, func_str, sid, sid, results, n_bytes_left,
- bytes_to_read);
-
if (bytes_to_read == 0)
{
if (flags & O_NONBLOCK)
{
if (!results)
- {
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
- "EAGAIN",
- getpid (), out_fd, out_fd, sid, sid);
- eagain = 1;
- }
+ eagain = 1;
goto update_offset;
}
else
nbytes = libc_read (in_fd, ldpw->io_buffer, bytes_to_read);
if (nbytes < 0)
{
- func_str = "libc_read";
- errno_val = errno;
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): in_fd (%d), "
- "io_buffer %p, bytes_to_read %lu, rv %d, "
- "errno %d", getpid (), out_fd, out_fd, func_str,
- in_fd, ldpw->io_buffer, bytes_to_read, nbytes,
- errno_val);
- errno = errno_val;
-
if (results == 0)
{
vec_reset_length (ldpw->io_buffer);
}
goto update_offset;
}
- func_str = "vppcom_session_write";
- if (LDP_DEBUG > 2)
- clib_warning
- ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
- "buf %p, nbytes %u: results %d, n_bytes_left %d", getpid (),
- out_fd, out_fd, func_str, sid, sid, ldpw->io_buffer, nbytes,
- results, n_bytes_left);
-
- size = vppcom_session_write (sid, ldpw->io_buffer, nbytes);
+
+ size = vls_write (vlsh, ldpw->io_buffer, nbytes);
if (size < 0)
{
if (size == VPPCOM_EAGAIN)
if (flags & O_NONBLOCK)
{
if (!results)
- {
- if (LDP_DEBUG > 2)
- clib_warning
- ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
- "EAGAIN", getpid (), out_fd, out_fd, sid, sid);
- eagain = 1;
- }
+ eagain = 1;
goto update_offset;
}
else
continue;
}
- else
- {
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s():"
- "sid %u, io_buffer %p, nbytes %u "
- "returned %d (%s)",
- getpid (), out_fd, out_fd, func_str,
- sid, ldpw->io_buffer, nbytes,
- size, vppcom_retval_str (size));
- }
if (results == 0)
{
vec_reset_length (ldpw->io_buffer);
off_t off = lseek (in_fd, *offset, SEEK_SET);
if (PREDICT_FALSE (off == -1))
{
- func_str = "lseek";
- errno_val = errno;
- clib_warning ("LDP<%d>: ERROR: %s(): SEEK_SET failed: "
- "in_fd %d, offset %p, *offset %ld, "
- "rv %ld, errno %d", getpid (), in_fd,
- offset, *offset, off, errno_val);
- errno = errno_val;
size = -1;
goto done;
}
}
else
{
- func_str = "libc_send";
-
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "in_fd %d, offset %p, len %u",
- getpid (), out_fd, out_fd, func_str,
- in_fd, offset, len);
-
size = libc_sendfile (out_fd, in_fd, offset, len);
}
done:
- if (LDP_DEBUG > 2)
- {
- if (size < 0)
- {
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), out_fd, out_fd,
- func_str, size, errno_val);
- errno = errno_val;
- }
- else
- clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
- getpid (), out_fd, out_fd, size, size);
- }
return size;
}
ssize_t
recv (int fd, void *buf, size_t n, int flags)
{
+ vls_handle_t vlsh;
ssize_t size;
- const char *func_str;
- u32 sid = ldp_sid_from_fd (fd);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
- func_str = "vppcom_session_recvfrom";
-
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x), buf %p, n %u, flags 0x%x", getpid (),
- fd, fd, func_str, sid, sid, buf, n, flags);
-
- size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
+ size = vls_recvfrom (vlsh, buf, n, flags, NULL);
if (size < 0)
{
errno = -size;
}
else
{
- func_str = "libc_recv";
-
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "buf %p, n %u, flags 0x%x", getpid (),
- fd, fd, func_str, buf, n, flags);
-
size = libc_recv (fd, buf, n, flags);
}
- if (LDP_DEBUG > 2)
- {
- if (size < 0)
- {
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), fd, fd,
- func_str, size, errno_val);
- errno = errno_val;
- }
- else
- clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
- getpid (), fd, fd, size, size);
- }
return size;
}
ssize_t
-sendto (int fd, const void *buf, size_t n, int flags,
- __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
+__recv_chk (int fd, void *buf, size_t n, size_t buflen, int flags)
{
- ssize_t size;
- const char *func_str = __func__;
- u32 sid = ldp_sid_from_fd (fd);
-
- if ((errno = -ldp_init ()))
+ if (n > buflen)
return -1;
- if (sid != INVALID_SESSION_ID)
- {
- vppcom_endpt_t *ep = 0;
- vppcom_endpt_t _ep;
+ return recv (fd, buf, n, flags);
+}
+
+static inline int
+ldp_vls_sendo (vls_handle_t vlsh, const void *buf, size_t n,
+ vppcom_endpt_tlv_t *app_tlvs, int flags,
+ __CONST_SOCKADDR_ARG _addr, socklen_t addr_len)
+{
+ const struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
+ vppcom_endpt_t *ep = 0;
+ vppcom_endpt_t _ep;
- if (addr)
+ _ep.app_tlvs = app_tlvs;
+
+ if (addr)
+ {
+ ep = &_ep;
+ switch (addr->sa_family)
{
- ep = &_ep;
- switch (addr->sa_family)
- {
- case AF_INET:
- ep->is_ip4 = VPPCOM_IS_IP4;
- ep->ip =
- (uint8_t *) & ((const struct sockaddr_in *) addr)->sin_addr;
- ep->port =
- (uint16_t) ((const struct sockaddr_in *) addr)->sin_port;
- break;
+ case AF_INET:
+ ep->is_ip4 = VPPCOM_IS_IP4;
+ ep->ip =
+ (uint8_t *) & ((const struct sockaddr_in *) addr)->sin_addr;
+ ep->port = (uint16_t) ((const struct sockaddr_in *) addr)->sin_port;
+ break;
- case AF_INET6:
- ep->is_ip4 = VPPCOM_IS_IP6;
- ep->ip =
- (uint8_t *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
- ep->port =
- (uint16_t) ((const struct sockaddr_in6 *) addr)->sin6_port;
- break;
+ case AF_INET6:
+ ep->is_ip4 = VPPCOM_IS_IP6;
+ ep->ip =
+ (uint8_t *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
+ ep->port =
+ (uint16_t) ((const struct sockaddr_in6 *) addr)->sin6_port;
+ break;
- default:
- errno = EAFNOSUPPORT;
- size = -1;
- goto done;
- }
+ default:
+ return EAFNOSUPPORT;
}
+ }
- func_str = "vppcom_session_sendto";
+ return vls_sendto (vlsh, (void *) buf, n, flags, ep);
+}
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
- getpid (), fd, fd, func_str, sid, sid, buf, n,
- flags, ep);
+static int
+ldp_vls_recvfrom (vls_handle_t vlsh, void *__restrict buf, size_t n, int flags,
+ __SOCKADDR_ARG _addr, socklen_t *__restrict addr_len)
+{
+ u8 src_addr[sizeof (struct sockaddr_in6)];
+ struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
+ vppcom_endpt_t ep;
+ ssize_t size;
+ int rv;
- size = vppcom_session_sendto (sid, (void *) buf, n, flags, ep);
- if (size < 0)
+ if (addr)
+ {
+ ep.ip = src_addr;
+ size = vls_recvfrom (vlsh, buf, n, flags, &ep);
+
+ if (size > 0)
{
- errno = -size;
- size = -1;
+ rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
+ if (rv < 0)
+ size = rv;
}
}
else
- {
- func_str = "libc_sendto";
+ size = vls_recvfrom (vlsh, buf, n, flags, NULL);
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
- getpid (), fd, fd, func_str, buf, n, flags,
- addr, addr_len);
+ return size;
+}
- size = libc_sendto (fd, buf, n, flags, addr, addr_len);
- }
+ssize_t
+sendto (int fd, const void *buf, size_t n, int flags,
+ __CONST_SOCKADDR_ARG _addr, socklen_t addr_len)
+{
+ const struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
+ vls_handle_t vlsh;
+ ssize_t size;
-done:
- if (LDP_DEBUG > 2)
+ ldp_init_check ();
+
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
+ size = ldp_vls_sendo (vlsh, buf, n, NULL, flags, addr, addr_len);
if (size < 0)
{
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), fd, fd,
- func_str, size, errno_val);
- errno = errno_val;
+ errno = -size;
+ size = -1;
}
- else
- clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
- getpid (), fd, fd, size, size);
}
+ else
+ {
+ size = libc_sendto (fd, buf, n, flags, addr, addr_len);
+ }
+
return size;
}
recvfrom (int fd, void *__restrict buf, size_t n, int flags,
__SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
{
+ vls_handle_t vlsh;
ssize_t size;
- const char *func_str;
- u32 sid = ldp_sid_from_fd (fd);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
- vppcom_endpt_t ep;
- u8 src_addr[sizeof (struct sockaddr_in6)];
-
- func_str = "vppcom_session_recvfrom";
-
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
- getpid (), fd, fd, func_str, sid, sid, buf, n,
- flags, &ep);
- if (addr)
- {
- ep.ip = src_addr;
- size = vppcom_session_recvfrom (sid, buf, n, flags, &ep);
-
- if (size > 0)
- size = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
- }
- else
- size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
-
+ size = ldp_vls_recvfrom (vlsh, buf, n, flags, addr, addr_len);
if (size < 0)
{
errno = -size;
}
else
{
- func_str = "libc_recvfrom";
+ size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
+ }
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
- getpid (), fd, fd, func_str, buf, n, flags,
- addr, addr_len);
+ return size;
+}
- size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
+static int
+ldp_parse_cmsg (vls_handle_t vlsh, const struct msghdr *msg,
+ vppcom_endpt_tlv_t **app_tlvs)
+{
+ uint8_t *ad, *at = (uint8_t *) *app_tlvs;
+ vppcom_endpt_tlv_t *adh;
+ struct in_pktinfo *pi;
+ struct cmsghdr *cmsg;
+
+ cmsg = CMSG_FIRSTHDR (msg);
+
+ while (cmsg != NULL)
+ {
+ switch (cmsg->cmsg_level)
+ {
+ case SOL_UDP:
+ switch (cmsg->cmsg_type)
+ {
+ case UDP_SEGMENT:
+ vec_add2 (at, adh, sizeof (*adh));
+ adh->data_type = VCL_UDP_SEGMENT;
+ adh->data_len = sizeof (uint16_t);
+ vec_add2 (at, ad, sizeof (uint16_t));
+ *(uint16_t *) ad = *(uint16_t *) CMSG_DATA (cmsg);
+ break;
+ default:
+ LDBG (1, "SOL_UDP cmsg_type %u not supported", cmsg->cmsg_type);
+ break;
+ }
+ break;
+ case SOL_IP:
+ switch (cmsg->cmsg_type)
+ {
+ case IP_PKTINFO:
+ vec_add2 (at, adh, sizeof (*adh));
+ adh->data_type = VCL_IP_PKTINFO;
+ adh->data_len = sizeof (struct in_addr);
+ vec_add2 (at, ad, sizeof (struct in_addr));
+ pi = (void *) CMSG_DATA (cmsg);
+ clib_memcpy_fast (ad, &pi->ipi_spec_dst,
+ sizeof (struct in_addr));
+ break;
+ default:
+ LDBG (1, "SOL_IP cmsg_type %u not supported", cmsg->cmsg_type);
+ break;
+ }
+ break;
+ default:
+ LDBG (1, "cmsg_level %u not supported", cmsg->cmsg_level);
+ break;
+ }
+ cmsg = CMSG_NXTHDR ((struct msghdr *) msg, cmsg);
}
+ *app_tlvs = (vppcom_endpt_tlv_t *) at;
+ return 0;
+}
- if (LDP_DEBUG > 2)
+static int
+ldp_make_cmsg (vls_handle_t vlsh, struct msghdr *msg)
+{
+ u32 optval, optlen = sizeof (optval);
+ struct cmsghdr *cmsg;
+
+ cmsg = CMSG_FIRSTHDR (msg);
+ memset (cmsg, 0, sizeof (*cmsg));
+
+ if (!vls_attr (vlsh, VPPCOM_ATTR_GET_IP_PKTINFO, (void *) &optval, &optlen))
+ return 0;
+
+ if (optval)
{
- if (size < 0)
+ vppcom_endpt_t ep;
+ u8 addr_buf[sizeof (struct in_addr)];
+ u32 size = sizeof (ep);
+
+ ep.ip = addr_buf;
+
+ if (!vls_attr (vlsh, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size))
{
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), fd, fd,
- func_str, size, errno_val);
- errno = errno_val;
+ struct in_pktinfo pi = {};
+
+ clib_memcpy (&pi.ipi_addr, ep.ip, sizeof (struct in_addr));
+ cmsg->cmsg_level = SOL_IP;
+ cmsg->cmsg_type = IP_PKTINFO;
+ cmsg->cmsg_len = CMSG_LEN (sizeof (pi));
+ clib_memcpy (CMSG_DATA (cmsg), &pi, sizeof (pi));
}
- else
- clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
- getpid (), fd, fd, size, size);
}
- return size;
+
+ return 0;
}
ssize_t
-sendmsg (int fd, const struct msghdr * message, int flags)
+sendmsg (int fd, const struct msghdr * msg, int flags)
{
+ vls_handle_t vlsh;
ssize_t size;
- const char *func_str;
- u32 sid = ldp_sid_from_fd (fd);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
- func_str = __func__;
+ vppcom_endpt_tlv_t *app_tlvs = 0;
+ struct iovec *iov = msg->msg_iov;
+ ssize_t total = 0;
+ int i, rv = 0;
- clib_warning ("LDP<%d>: LDP-TBD", getpid ());
- errno = ENOSYS;
- size = -1;
- }
- else
- {
- func_str = "libc_sendmsg";
+ ldp_parse_cmsg (vlsh, msg, &app_tlvs);
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "message %p, flags 0x%x",
- getpid (), fd, fd, func_str, message, flags);
+ for (i = 0; i < msg->msg_iovlen; ++i)
+ {
+ rv = ldp_vls_sendo (vlsh, iov[i].iov_base, iov[i].iov_len, app_tlvs,
+ flags, msg->msg_name, msg->msg_namelen);
+ if (rv < 0)
+ break;
+ else
+ {
+ total += rv;
+ if (rv < iov[i].iov_len)
+ break;
+ }
+ }
- size = libc_sendmsg (fd, message, flags);
- }
+ vec_free (app_tlvs);
- if (LDP_DEBUG > 2)
- {
- if (size < 0)
+ if (rv < 0 && total == 0)
{
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), fd, fd,
- func_str, size, errno_val);
- errno = errno_val;
+ errno = -rv;
+ size = -1;
}
else
- clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
- getpid (), fd, fd, size, size);
+ size = total;
+ }
+ else
+ {
+ size = libc_sendmsg (fd, msg, flags);
}
+
return size;
}
-#ifdef USE_GNU
+#ifdef _GNU_SOURCE
int
sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
{
ssize_t size;
const char *func_str;
- u32 sid = ldp_sid_from_fd (fd);
+ u32 sh = ldp_fd_to_vlsh (fd);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ if (sh != VLS_INVALID_HANDLE)
{
clib_warning ("LDP<%d>: LDP-TBD", getpid ());
errno = ENOSYS;
#endif
ssize_t
-recvmsg (int fd, struct msghdr * message, int flags)
+recvmsg (int fd, struct msghdr * msg, int flags)
{
+ vls_handle_t vlsh;
ssize_t size;
- const char *func_str;
- u32 sid = ldp_sid_from_fd (fd);
- if ((errno = -ldp_init ()))
- return -1;
-
- if (sid != INVALID_SESSION_ID)
- {
- func_str = __func__;
+ ldp_init_check ();
- clib_warning ("LDP<%d>: LDP-TBD", getpid ());
- errno = ENOSYS;
- size = -1;
- }
- else
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
- func_str = "libc_recvmsg";
+ struct iovec *iov = msg->msg_iov;
+ ssize_t max_deq, total = 0;
+ int i, rv = 0;
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "message %p, flags 0x%x",
- getpid (), fd, fd, func_str, message, flags);
+ max_deq = vls_attr (vlsh, VPPCOM_ATTR_GET_NREAD, 0, 0);
+ if (!max_deq)
+ return 0;
- size = libc_recvmsg (fd, message, flags);
- }
+ for (i = 0; i < msg->msg_iovlen; i++)
+ {
+ rv = ldp_vls_recvfrom (vlsh, iov[i].iov_base, iov[i].iov_len, flags,
+ (i == 0 ? msg->msg_name : NULL),
+ (i == 0 ? &msg->msg_namelen : NULL));
+ if (rv <= 0)
+ break;
+ else
+ {
+ total += rv;
+ if (rv < iov[i].iov_len)
+ break;
+ }
+ if (total >= max_deq)
+ break;
+ }
- if (LDP_DEBUG > 2)
- {
- if (size < 0)
+ if (rv < 0 && total == 0)
{
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), fd, fd,
- func_str, size, errno_val);
- errno = errno_val;
+ errno = -rv;
+ size = -1;
}
else
- clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
- getpid (), fd, fd, size, size);
+ {
+ if (msg->msg_controllen)
+ ldp_make_cmsg (vlsh, msg);
+ size = total;
+ }
}
+ else
+ {
+ size = libc_recvmsg (fd, msg, flags);
+ }
+
return size;
}
-#ifdef USE_GNU
+#ifdef _GNU_SOURCE
int
recvmmsg (int fd, struct mmsghdr *vmessages,
unsigned int vlen, int flags, struct timespec *tmo)
{
- ssize_t size;
- const char *func_str;
- u32 sid = ldp_sid_from_fd (fd);
-
- if ((errno = -ldp_init ()))
- return -1;
-
- if (sid != INVALID_SESSION_ID)
- {
- clib_warning ("LDP<%d>: LDP-TBD", getpid ());
- errno = ENOSYS;
- size = -1;
- }
- else
- {
- func_str = "libc_recvmmsg";
-
- if (LDP_DEBUG > 2)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "vmessages %p, vlen %u, flags 0x%x, tmo %p",
- getpid (), fd, fd, func_str, vmessages, vlen,
- flags, tmo);
+ ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
+ u32 sh;
- size = libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
- }
+ ldp_init_check ();
- if (LDP_DEBUG > 2)
+ sh = ldp_fd_to_vlsh (fd);
+
+ if (sh != VLS_INVALID_HANDLE)
{
- if (size < 0)
+ struct mmsghdr *mh;
+ ssize_t rv = 0;
+ u32 nvecs = 0;
+ f64 time_out;
+
+ if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
+ clib_time_init (&ldpw->clib_time);
+ if (tmo)
{
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), fd, fd,
- func_str, size, errno_val);
- errno = errno_val;
+ time_out = (f64) tmo->tv_sec + (f64) tmo->tv_nsec / (f64) 1e9;
+ time_out += clib_time_now (&ldpw->clib_time);
}
else
- clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
- getpid (), fd, fd, size, size);
+ {
+ time_out = (f64) ~0;
+ }
+
+ while (nvecs < vlen)
+ {
+ mh = &vmessages[nvecs];
+ rv = recvmsg (fd, &mh->msg_hdr, flags);
+ if (rv > 0)
+ {
+ mh->msg_len = rv;
+ nvecs += 1;
+ continue;
+ }
+
+ if (!time_out || clib_time_now (&ldpw->clib_time) >= time_out)
+ break;
+
+ usleep (1);
+ }
+
+ return nvecs > 0 ? nvecs : rv;
+ }
+ else
+ {
+ return libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
}
- return size;
}
#endif
getsockopt (int fd, int level, int optname,
void *__restrict optval, socklen_t * __restrict optlen)
{
+ vls_handle_t vlsh;
int rv;
- const char *func_str = __func__;
- u32 sid = ldp_sid_from_fd (fd);
- u32 buflen = optlen ? (u32) * optlen : 0;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
rv = -EOPNOTSUPP;
switch (optname)
{
case TCP_NODELAY:
- func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_NODELAY]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_NODELAY,
- optval, optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_NODELAY,
+ optval, optlen);
break;
case TCP_MAXSEG:
- func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_USER_MSS]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_USER_MSS,
- optval, optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_USER_MSS,
+ optval, optlen);
break;
case TCP_KEEPIDLE:
- func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPIDLE]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
- optval, optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
+ optval, optlen);
break;
case TCP_KEEPINTVL:
- func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPINTVL]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x), SOL_TCP",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
- optval, optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
+ optval, optlen);
break;
case TCP_INFO:
if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
{
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x), "
- "SOL_TCP, TCP_INFO, optval %p, "
- "optlen %d: #LDP-NOP#",
- getpid (), fd, fd, sid, sid,
- optval, *optlen);
+ LDBG (1, "fd %d: vlsh %u SOL_TCP, TCP_INFO, optval %p, "
+ "optlen %d: #LDP-NOP#", fd, vlsh, optval, *optlen);
memset (optval, 0, *optlen);
rv = VPPCOM_OK;
}
else
rv = -EFAULT;
break;
+ case TCP_CONGESTION:
+ *optlen = strlen ("cubic");
+ strncpy (optval, "cubic", *optlen + 1);
+ rv = 0;
+ break;
+ default:
+ LDBG (0, "ERROR: fd %d: getsockopt SOL_TCP: sid %u, "
+ "optname %d unsupported!", fd, vlsh, optname);
+ break;
+ }
+ break;
+ case SOL_IP:
+ switch (optname)
+ {
+ case SO_ORIGINAL_DST:
+ rv =
+ vls_attr (vlsh, VPPCOM_ATTR_GET_ORIGINAL_DST, optval, optlen);
+ break;
default:
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
- "sid %u (0x%x), SOL_TCP, "
- "optname %d unsupported!",
- getpid (), fd, fd, func_str, sid, sid, optname);
+ LDBG (0,
+ "ERROR: fd %d: getsockopt SOL_IP: vlsh %u "
+ "optname %d unsupported!",
+ fd, vlsh, optname);
break;
}
break;
switch (optname)
{
case IPV6_V6ONLY:
- func_str = "vppcom_session_attr[SOL_IPV6,GET_V6ONLY]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_V6ONLY,
- optval, optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_V6ONLY, optval, optlen);
break;
default:
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
- "sid %u (0x%x), SOL_IPV6, "
- "optname %d unsupported!",
- getpid (), fd, fd, func_str, sid, sid, optname);
+ LDBG (0, "ERROR: fd %d: getsockopt SOL_IPV6: vlsh %u "
+ "optname %d unsupported!", fd, vlsh, optname);
break;
}
break;
switch (optname)
{
case SO_ACCEPTCONN:
- func_str = "vppcom_session_attr[SOL_SOCKET,GET_ACCEPTCONN]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LISTEN,
- optval, optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_LISTEN, optval, optlen);
break;
case SO_KEEPALIVE:
- func_str = "vppcom_session_attr[SOL_SOCKET,GET_KEEPALIVE]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_KEEPALIVE,
- optval, optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_KEEPALIVE, optval, optlen);
break;
case SO_PROTOCOL:
- func_str = "vppcom_session_attr[SOL_SOCKET,GET_PROTOCOL]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PROTOCOL,
- optval, optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_PROTOCOL, optval, optlen);
*(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
break;
case SO_SNDBUF:
- func_str = "vppcom_session_attr[SOL_SOCKET,GET_TX_FIFO_LEN]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x), optlen %d",
- getpid (), fd, fd, func_str, sid, sid, buflen);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TX_FIFO_LEN,
- optval, optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TX_FIFO_LEN,
+ optval, optlen);
break;
case SO_RCVBUF:
- func_str = "vppcom_session_attr[SOL_SOCKET,GET_RX_FIFO_LEN]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x), optlen %d",
- getpid (), fd, fd, func_str, sid, sid, buflen);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_RX_FIFO_LEN,
- optval, optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_RX_FIFO_LEN,
+ optval, optlen);
break;
case SO_REUSEADDR:
- func_str = "vppcom_session_attr[SOL_SOCKET,GET_REUSEADDR]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REUSEADDR,
- optval, optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_REUSEADDR, optval, optlen);
+ break;
+ case SO_REUSEPORT:
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_REUSEPORT, optval, optlen);
break;
case SO_BROADCAST:
- func_str = "vppcom_session_attr[SOL_SOCKET,GET_BROADCAST]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_BROADCAST,
- optval, optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_BROADCAST, optval, optlen);
+ break;
+ case SO_DOMAIN:
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_DOMAIN, optval, optlen);
break;
case SO_ERROR:
- func_str = "vppcom_session_attr[SOL_SOCKET,GET_ERROR]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_ERROR,
- optval, optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_ERROR, optval, optlen);
+ break;
+ case SO_BINDTODEVICE:
+ rv = 0;
break;
default:
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
- "sid %u (0x%x), SOL_SOCKET, "
- "optname %d unsupported!",
- getpid (), fd, fd, func_str, sid, sid, optname);
+ LDBG (0, "ERROR: fd %d: getsockopt SOL_SOCKET: vlsh %u "
+ "optname %d unsupported!", fd, vlsh, optname);
break;
}
break;
}
else
{
- func_str = "libc_getsockopt";
-
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
- "optname %d, optval %p, optlen %d",
- getpid (), fd, fd, func_str, level, optname,
- optval, optlen);
-
rv = libc_getsockopt (fd, level, optname, optval, optlen);
}
- if (LDP_DEBUG > 1)
- {
- if (rv < 0)
- {
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), fd, fd,
- func_str, rv, errno_val);
- errno = errno_val;
- }
- else
- clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
- getpid (), fd, fd, rv, rv);
- }
return rv;
}
setsockopt (int fd, int level, int optname,
const void *optval, socklen_t optlen)
{
+ vls_handle_t vlsh;
int rv;
- const char *func_str = __func__;
- u32 sid = ldp_sid_from_fd (fd);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
rv = -EOPNOTSUPP;
switch (optname)
{
case TCP_NODELAY:
- func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_NODELAY]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_NODELAY,
- (void *) optval, &optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_NODELAY,
+ (void *) optval, &optlen);
break;
case TCP_MAXSEG:
- func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_USER_MSS]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_USER_MSS,
- (void *) optval, &optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_USER_MSS,
+ (void *) optval, &optlen);
break;
case TCP_KEEPIDLE:
- func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPIDLE]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
- (void *) optval, &optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
+ (void *) optval, &optlen);
break;
case TCP_KEEPINTVL:
- func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPINTVL]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x), SOL_TCP",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
- (void *) optval, &optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
+ (void *) optval, &optlen);
+ break;
+ case TCP_CONGESTION:
+ case TCP_CORK:
+ /* Ignore */
+ rv = 0;
break;
default:
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
- "sid %u (0x%x), SOL_TCP, "
- "optname %d unsupported!",
- getpid (), fd, fd, func_str, sid, sid, optname);
+ LDBG (0, "ERROR: fd %d: setsockopt() SOL_TCP: vlsh %u"
+ "optname %d unsupported!", fd, vlsh, optname);
break;
}
break;
switch (optname)
{
case IPV6_V6ONLY:
- func_str = "vppcom_session_attr[SOL_IPV6,SET_V6ONLY]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_V6ONLY,
- (void *) optval, &optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_V6ONLY,
+ (void *) optval, &optlen);
break;
default:
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
- "sid %u (0x%x), SOL_IPV6, "
- "optname %d unsupported!",
- getpid (), fd, fd, func_str, sid, sid, optname);
+ LDBG (0, "ERROR: fd %d: setsockopt SOL_IPV6: vlsh %u"
+ "optname %d unsupported!", fd, vlsh, optname);
break;
}
break;
switch (optname)
{
case SO_KEEPALIVE:
- func_str = "vppcom_session_attr[SOL_SOCKET,SET_KEEPALIVE]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_KEEPALIVE,
- (void *) optval, &optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_KEEPALIVE,
+ (void *) optval, &optlen);
break;
case SO_REUSEADDR:
- func_str = "vppcom_session_attr[SOL_SOCKET,SET_REUSEADDR]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_REUSEADDR,
- (void *) optval, &optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_REUSEADDR,
+ (void *) optval, &optlen);
+ break;
+ case SO_REUSEPORT:
+ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_REUSEPORT, (void *) optval,
+ &optlen);
break;
case SO_BROADCAST:
- func_str = "vppcom_session_attr[SOL_SOCKET,SET_BROADCAST]";
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
- "sid %u (0x%x)",
- getpid (), fd, fd, func_str, sid, sid);
- rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_BROADCAST,
- (void *) optval, &optlen);
+ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_BROADCAST,
+ (void *) optval, &optlen);
+ break;
+ case SO_LINGER:
+ rv = 0;
+ break;
+ default:
+ LDBG (0, "ERROR: fd %d: setsockopt SOL_SOCKET: vlsh %u "
+ "optname %d unsupported!", fd, vlsh, optname);
+ break;
+ }
+ break;
+ case SOL_IP:
+ switch (optname)
+ {
+ case IP_PKTINFO:
+ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_IP_PKTINFO, (void *) optval,
+ &optlen);
break;
default:
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
- "sid %u (0x%x), SOL_SOCKET, "
- "optname %d unsupported!",
- getpid (), fd, fd, func_str, sid, sid, optname);
+ LDBG (0,
+ "ERROR: fd %d: setsockopt SOL_IP: vlsh %u optname %d"
+ "unsupported!",
+ fd, vlsh, optname);
break;
}
break;
}
else
{
- func_str = "libc_setsockopt";
-
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
- "optname %d, optval %p, optlen %d",
- getpid (), fd, fd, func_str, level, optname,
- optval, optlen);
-
rv = libc_setsockopt (fd, level, optname, optval, optlen);
}
- if (LDP_DEBUG > 1)
- {
- if (rv < 0)
- {
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), fd, fd,
- func_str, rv, errno_val);
- errno = errno_val;
- }
- else
- clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
- getpid (), fd, fd, rv, rv);
- }
return rv;
}
int
listen (int fd, int n)
{
+ vls_handle_t vlsh;
int rv;
- u32 sid = ldp_sid_from_fd (fd);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
- LDBG (0, "fd %d (0x%x): calling vppcom_session_listen():"
- " sid %u (0x%x), n %d", fd, fd, sid, sid, n);
+ LDBG (0, "fd %d: calling vls_listen: vlsh %u, n %d", fd, vlsh, n);
- rv = vppcom_session_listen (sid, n);
+ rv = vls_listen (vlsh, n);
if (rv != VPPCOM_OK)
{
errno = -rv;
}
else
{
- LDBG (0, "fd %d (0x%x): calling libc_listen(): n %d", fd, fd, n);
-
+ LDBG (0, "fd %d: calling libc_listen(): n %d", fd, n);
rv = libc_listen (fd, n);
}
- LDBG (1, "fd %d (0x%x): returning %d (0x%x)", fd, fd, rv, rv);
+ LDBG (1, "fd %d: returning %d", fd, rv);
return rv;
}
static inline int
-ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
- socklen_t * __restrict addr_len, int flags)
+ldp_accept4 (int listen_fd, __SOCKADDR_ARG _addr,
+ socklen_t *__restrict addr_len, int flags)
{
+ struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
+ vls_handle_t listen_vlsh, accept_vlsh;
int rv;
- u32 listen_sid = ldp_sid_from_fd (listen_fd);
- int accept_sid;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (listen_sid != INVALID_SESSION_ID)
+ listen_vlsh = ldp_fd_to_vlsh (listen_fd);
+ if (listen_vlsh != VLS_INVALID_HANDLE)
{
vppcom_endpt_t ep;
u8 src_addr[sizeof (struct sockaddr_in6)];
memset (&ep, 0, sizeof (ep));
ep.ip = src_addr;
- LDBG (0, "listen fd %d (0x%x): calling vppcom_session_accept:"
- " listen sid %u (0x%x), ep %p, flags 0x%x", listen_fd,
- listen_fd, listen_sid, listen_sid, ep, flags);
+ LDBG (0, "listen fd %d: calling vppcom_session_accept: listen sid %u,"
+ " ep %p, flags 0x%x", listen_fd, listen_vlsh, &ep, flags);
- accept_sid = vppcom_session_accept (listen_sid, &ep, flags);
- if (accept_sid < 0)
+ accept_vlsh = vls_accept (listen_vlsh, &ep, flags);
+ if (accept_vlsh < 0)
{
- errno = -accept_sid;
+ errno = -accept_vlsh;
rv = -1;
}
else
rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
if (rv != VPPCOM_OK)
{
- (void) vppcom_session_close ((u32) accept_sid);
+ (void) vls_close (accept_vlsh);
errno = -rv;
rv = -1;
}
else
{
- rv = ldp_fd_alloc ((u32) accept_sid);
- if (rv < 0)
- {
- (void) vppcom_session_close ((u32) accept_sid);
- errno = -rv;
- rv = -1;
- }
+ rv = ldp_vlsh_to_fd (accept_vlsh);
}
}
}
else
{
- LDBG (0, "listen fd %d (0x%x): calling libc_accept4(): "
- "addr %p, addr_len %p, flags 0x%x", listen_fd,
- listen_fd, addr, addr_len, flags);
+ LDBG (0, "listen fd %d: calling libc_accept4(): addr %p, addr_len %p,"
+ " flags 0x%x", listen_fd, addr, addr_len, flags);
rv = libc_accept4 (listen_fd, addr, addr_len, flags);
}
- LDBG (1, "listen fd %d (0x%x): returning %d (0x%x)", listen_fd, listen_fd,
- rv, rv);
+ LDBG (1, "listen fd %d: accept returning %d", listen_fd, rv);
return rv;
}
int
shutdown (int fd, int how)
{
- int rv;
- const char *func_str;
- u32 sid = ldp_sid_from_fd (fd);
+ vls_handle_t vlsh;
+ int rv = 0;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
- func_str = "vppcom_session_close[TODO]";
- rv = close (fd);
+ LDBG (0, "called shutdown: fd %u vlsh %u how %d", fd, vlsh, how);
+ rv = vls_shutdown (vlsh, how);
}
else
{
- func_str = "libc_shutdown";
-
- if (LDP_DEBUG > 1)
- clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): how %d",
- getpid (), fd, fd, func_str, how);
-
+ LDBG (0, "fd %d: calling libc_shutdown: how %d", fd, how);
rv = libc_shutdown (fd, how);
}
- if (LDP_DEBUG > 1)
- {
- if (rv < 0)
- {
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), fd, fd,
- func_str, rv, errno_val);
- errno = errno_val;
- }
- else
- clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
- getpid (), fd, fd, rv, rv);
- }
return rv;
}
epoll_create1 (int flags)
{
ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
- const char *func_str;
+ vls_handle_t vlsh;
int rv;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (ldp->vcl_needs_real_epoll)
+ if (ldp->vcl_needs_real_epoll || vls_use_real_epoll ())
{
+ /* Make sure workers have been allocated */
+ if (!ldp->workers)
+ {
+ ldp_alloc_workers ();
+ ldpw = ldp_worker_get_current ();
+ }
rv = libc_epoll_create1 (flags);
ldp->vcl_needs_real_epoll = 0;
ldpw->vcl_mq_epfd = rv;
LDBG (0, "created vcl epfd %u", rv);
return rv;
}
- func_str = "vppcom_epoll_create";
- LDBG (1, "calling %s()", func_str);
-
- rv = vppcom_epoll_create ();
-
- if (PREDICT_FALSE (rv < 0))
+ vlsh = vls_epoll_create ();
+ if (PREDICT_FALSE (vlsh == VLS_INVALID_HANDLE))
{
- errno = -rv;
+ errno = -vlsh;
rv = -1;
}
else
- rv = ldp_fd_alloc ((u32) rv);
-
- if (LDP_DEBUG > 1)
{
- if (rv < 0)
- {
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: %s() failed! "
- "rv %d, errno = %d",
- getpid (), func_str, rv, errno_val);
- errno = errno_val;
- }
- else
- clib_warning ("LDP<%d>: returning epfd %d (0x%x)", getpid (), rv, rv);
+ rv = ldp_vlsh_to_fd (vlsh);
}
+ LDBG (0, "epoll_create epfd %u vlsh %u", rv, vlsh);
return rv;
}
int
epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
{
- u32 vep_idx = ldp_sid_from_fd (epfd), sid;
- const char *func_str;
+ vls_handle_t vep_vlsh, vlsh;
int rv;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
- if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
+ vep_vlsh = ldp_fd_to_vlsh (epfd);
+ if (PREDICT_FALSE (vep_vlsh == VLS_INVALID_HANDLE))
{
/* The LDP epoll_create1 always creates VCL epfd's.
* The app should never have a kernel base epoll fd unless it
* was acquired outside of the LD_PRELOAD process context.
* In any case, if we get one, punt it to libc_epoll_ctl.
*/
- func_str = "libc_epoll_ctl";
-
- LDBG (1, "epfd %d (0x%x): calling %s(): op %d, fd %d (0x%x),"
- " event %p", epfd, epfd, func_str, op, fd, fd, event);
+ LDBG (1,
+ "epfd %d: calling libc_epoll_ctl: op %d, fd %d"
+ " events 0x%x",
+ epfd, op, fd, event ? event->events : 0);
rv = libc_epoll_ctl (epfd, op, fd, event);
goto done;
}
- sid = ldp_sid_from_fd (fd);
+ vlsh = ldp_fd_to_vlsh (fd);
- LDBG (0, "epfd %d (0x%x), vep_idx %d (0x%x), sid %d (0x%x)",
- epfd, epfd, vep_idx, vep_idx, sid, sid);
+ LDBG (0, "epfd %d ep_vlsh %d, fd %u vlsh %d, op %u", epfd, vep_vlsh, fd,
+ vlsh, op);
- if (sid != INVALID_SESSION_ID)
+ if (vlsh != VLS_INVALID_HANDLE)
{
- func_str = "vppcom_epoll_ctl";
+ LDBG (1,
+ "epfd %d: calling vls_epoll_ctl: ep_vlsh %d op %d, vlsh %u,"
+ " events 0x%x",
+ epfd, vep_vlsh, op, vlsh, event ? event->events : 0);
- LDBG (1, "epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
- " op %d, sid %u (0x%x), event %p", epfd, epfd,
- func_str, vep_idx, vep_idx, sid, sid, event);
-
- rv = vppcom_epoll_ctl (vep_idx, op, sid, event);
+ rv = vls_epoll_ctl (vep_vlsh, op, vlsh, event);
if (rv != VPPCOM_OK)
{
errno = -rv;
int libc_epfd;
u32 size = sizeof (epfd);
- func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
- libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0,
- 0);
- LDBG (1, "epfd %d (0x%x), vep_idx %d (0x%x): %s() "
- "returned libc_epfd %d (0x%x)", epfd, epfd,
- vep_idx, vep_idx, func_str, libc_epfd, libc_epfd);
-
+ libc_epfd = vls_attr (vep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
if (!libc_epfd)
{
- func_str = "libc_epoll_create1";
-
- LDBG (1, "epfd %d (0x%x), vep_idx %d (0x%x): "
- "calling %s(): EPOLL_CLOEXEC", epfd, epfd,
- vep_idx, vep_idx, func_str);
+ LDBG (1, "epfd %d, vep_vlsh %d calling libc_epoll_create1: "
+ "EPOLL_CLOEXEC", epfd, vep_vlsh);
libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
if (libc_epfd < 0)
goto done;
}
- func_str = "vppcom_session_attr[SET_LIBC_EPFD]";
- LDBG (1, "epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
- " VPPCOM_ATTR_SET_LIBC_EPFD, libc_epfd %d (0x%x), size %d",
- epfd, epfd, func_str, vep_idx, vep_idx, libc_epfd,
- libc_epfd, size);
-
- rv = vppcom_session_attr (vep_idx, VPPCOM_ATTR_SET_LIBC_EPFD,
- &libc_epfd, &size);
+ rv = vls_attr (vep_vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd,
+ &size);
if (rv < 0)
{
errno = -rv;
goto done;
}
- func_str = "libc_epoll_ctl";
-
- LDBG (1, "epfd %d (0x%x): calling %s(): libc_epfd %d (0x%x), "
- "op %d, fd %d (0x%x), event %p", epfd, epfd, func_str,
- libc_epfd, libc_epfd, op, fd, fd, event);
+ LDBG (1, "epfd %d: calling libc_epoll_ctl: libc_epfd %d, op %d, fd %d,"
+ " event %p", epfd, libc_epfd, op, fd, event);
rv = libc_epoll_ctl (libc_epfd, op, fd, event);
}
done:
- if (LDP_DEBUG > 1)
- {
- if (rv < 0)
- {
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), fd, fd,
- func_str, rv, errno_val);
- errno = errno_val;
- }
- else
- clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
- getpid (), fd, fd, rv, rv);
- }
return rv;
}
ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
int timeout, const sigset_t * sigmask)
{
- ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
- double time_to_wait = (double) 0, time_out, now = 0;
- u32 vep_idx = ldp_sid_from_fd (epfd);
+ ldp_worker_ctx_t *ldpw;
+ double time_to_wait = (double) 0, max_time;
int libc_epfd, rv = 0;
- const char *func_str;
+ vls_handle_t ep_vlsh;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
if (PREDICT_FALSE (!events || (timeout < -1)))
{
return -1;
}
+ if (PREDICT_FALSE (vppcom_worker_index () == ~0))
+ vls_register_vcl_worker ();
+
+ ldpw = ldp_worker_get_current ();
if (epfd == ldpw->vcl_mq_epfd)
return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
- if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
+ ep_vlsh = ldp_fd_to_vlsh (epfd);
+ if (PREDICT_FALSE (ep_vlsh == VLS_INVALID_HANDLE))
{
- clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): bad vep_idx %d (0x%x)!",
- getpid (), epfd, epfd, vep_idx, vep_idx);
+ LDBG (0, "epfd %d: bad ep_vlsh %d!", epfd, ep_vlsh);
errno = EBADFD;
return -1;
}
- time_to_wait = ((timeout >= 0) ? (double) timeout : 0);
- time_out = clib_time_now (&ldpw->clib_time) + time_to_wait;
+ if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
+ clib_time_init (&ldpw->clib_time);
+ time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0);
+ max_time = clib_time_now (&ldpw->clib_time) + time_to_wait;
- func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
- libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
+ libc_epfd = vls_attr (ep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
if (PREDICT_FALSE (libc_epfd < 0))
{
errno = -libc_epfd;
goto done;
}
- LDBG (2, "epfd %d (0x%x): vep_idx %d (0x%x), libc_epfd %d (0x%x), "
- "events %p, maxevents %d, timeout %d, sigmask %p: time_to_wait %.02f",
- epfd, epfd, vep_idx, vep_idx, libc_epfd, libc_epfd, events,
- maxevents, timeout, sigmask, time_to_wait, time_out);
+ LDBG (2, "epfd %d: vep_idx %d, libc_epfd %d, events %p, maxevents %d, "
+ "timeout %d, sigmask %p: time_to_wait %.02f", epfd, ep_vlsh,
+ libc_epfd, events, maxevents, timeout, sigmask, time_to_wait);
do
{
if (!ldpw->epoll_wait_vcl)
{
- func_str = "vppcom_epoll_wait";
-
- LDBG (3, "epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
- " events %p, maxevents %d", epfd, epfd, func_str,
- vep_idx, vep_idx, events, maxevents);
-
- rv = vppcom_epoll_wait (vep_idx, events, maxevents, 0);
+ rv = vls_epoll_wait (ep_vlsh, events, maxevents, 0);
if (rv > 0)
{
ldpw->epoll_wait_vcl = 1;
if (libc_epfd > 0)
{
- func_str = "libc_epoll_pwait";
-
- LDBG (3, "epfd %d (0x%x): calling %s(): libc_epfd %d "
- "(0x%x), events %p, maxevents %d, sigmask %p",
- epfd, epfd, func_str, libc_epfd, libc_epfd, events,
- maxevents, sigmask);
-
- rv = libc_epoll_pwait (libc_epfd, events, maxevents, 1, sigmask);
+ rv = libc_epoll_pwait (libc_epfd, events, maxevents, 0, sigmask);
if (rv != 0)
goto done;
}
-
- if (timeout != -1)
- now = clib_time_now (&ldpw->clib_time);
}
- while (now < time_out);
+ while ((timeout == -1) || (clib_time_now (&ldpw->clib_time) < max_time));
done:
- if (LDP_DEBUG > 3)
+ return rv;
+}
+
+static inline int
+ldp_epoll_pwait_eventfd (int epfd, struct epoll_event *events,
+ int maxevents, int timeout, const sigset_t * sigmask)
+{
+ int libc_epfd, rv = 0, num_ev, libc_num_ev, vcl_wups = 0;
+ struct epoll_event *libc_evts;
+ ldp_worker_ctx_t *ldpw;
+ vls_handle_t ep_vlsh;
+
+ ldp_init_check ();
+
+ if (PREDICT_FALSE (!events || (timeout < -1)))
{
- if (libc_epfd > 0)
- epfd = libc_epfd;
+ errno = EFAULT;
+ return -1;
+ }
+
+ /* Make sure the vcl worker is valid. Could be that epoll fd was created on
+ * one thread but it is now used on another */
+ if (PREDICT_FALSE (vppcom_worker_index () == ~0))
+ vls_register_vcl_worker ();
+
+ ldpw = ldp_worker_get_current ();
+ if (epfd == ldpw->vcl_mq_epfd)
+ return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
+
+ ep_vlsh = ldp_fd_to_vlsh (epfd);
+ if (PREDICT_FALSE (ep_vlsh == VLS_INVALID_HANDLE))
+ {
+ LDBG (0, "epfd %d: bad ep_vlsh %d!", epfd, ep_vlsh);
+ errno = EBADFD;
+ return -1;
+ }
+
+ libc_epfd = vls_attr (ep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
+ if (PREDICT_FALSE (!libc_epfd))
+ {
+ u32 size = sizeof (epfd);
+
+ LDBG (1, "epfd %d, vep_vlsh %d calling libc_epoll_create1: "
+ "EPOLL_CLOEXEC", epfd, ep_vlsh);
+ libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
+ if (libc_epfd < 0)
+ {
+ rv = libc_epfd;
+ goto done;
+ }
+
+ rv = vls_attr (ep_vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd, &size);
if (rv < 0)
{
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): %s() failed! "
- "rv %d, errno = %d", getpid (), epfd, epfd,
- func_str, rv, errno_val);
- errno = errno_val;
+ errno = -rv;
+ rv = -1;
+ goto done;
}
- else
- clib_warning ("LDP<%d>: epfd %d (0x%x): returning %d (0x%x)",
- getpid (), epfd, epfd, rv, rv);
}
+ if (PREDICT_FALSE (libc_epfd <= 0))
+ {
+ errno = -libc_epfd;
+ rv = -1;
+ goto done;
+ }
+
+ if (PREDICT_FALSE (!ldpw->mq_epfd_added))
+ {
+ struct epoll_event e = { 0 };
+ e.events = EPOLLIN;
+ e.data.fd = ldpw->vcl_mq_epfd;
+ if (libc_epoll_ctl (libc_epfd, EPOLL_CTL_ADD, ldpw->vcl_mq_epfd, &e) <
+ 0)
+ {
+ LDBG (0, "epfd %d, add libc mq epoll fd %d to libc epoll fd %d",
+ epfd, ldpw->vcl_mq_epfd, libc_epfd);
+ rv = -1;
+ goto done;
+ }
+ ldpw->mq_epfd_added = 1;
+ }
+
+ /* Request to only drain unhandled to prevent libc_epoll_wait starved */
+ rv = vls_epoll_wait (ep_vlsh, events, maxevents, -2);
+ if (rv > 0)
+ {
+ timeout = 0;
+ if (rv >= maxevents)
+ goto done;
+ maxevents -= rv;
+ }
+ else if (PREDICT_FALSE (rv < 0))
+ {
+ errno = -rv;
+ rv = -1;
+ goto done;
+ }
+
+epoll_again:
+
+ libc_evts = &events[rv];
+ libc_num_ev =
+ libc_epoll_pwait (libc_epfd, libc_evts, maxevents, timeout, sigmask);
+ if (libc_num_ev <= 0)
+ {
+ rv = rv >= 0 ? rv : -1;
+ goto done;
+ }
+
+ for (int i = 0; i < libc_num_ev; i++)
+ {
+ if (libc_evts[i].data.fd == ldpw->vcl_mq_epfd)
+ {
+ /* We should remove mq epoll fd from events. */
+ libc_num_ev--;
+ if (i != libc_num_ev)
+ {
+ libc_evts[i].events = libc_evts[libc_num_ev].events;
+ libc_evts[i].data.u64 = libc_evts[libc_num_ev].data.u64;
+ }
+ num_ev = vls_epoll_wait (ep_vlsh, &libc_evts[libc_num_ev],
+ maxevents - libc_num_ev, 0);
+ if (PREDICT_TRUE (num_ev > 0))
+ rv += num_ev;
+ /* Woken up by vcl but no events generated. Accept it once */
+ if (rv == 0 && libc_num_ev == 0 && timeout && vcl_wups++ < 1)
+ goto epoll_again;
+ break;
+ }
+ }
+
+ rv += libc_num_ev;
+
+done:
return rv;
}
epoll_pwait (int epfd, struct epoll_event *events,
int maxevents, int timeout, const sigset_t * sigmask)
{
- return ldp_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
+ if (vls_use_eventfd ())
+ return ldp_epoll_pwait_eventfd (epfd, events, maxevents, timeout,
+ sigmask);
+ else
+ return ldp_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
}
int
epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
{
- return ldp_epoll_pwait (epfd, events, maxevents, timeout, NULL);
+ if (vls_use_eventfd ())
+ return ldp_epoll_pwait_eventfd (epfd, events, maxevents, timeout, NULL);
+ else
+ return ldp_epoll_pwait (epfd, events, maxevents, timeout, NULL);
}
int
poll (struct pollfd *fds, nfds_t nfds, int timeout)
{
ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
- const char *func_str = __func__;
int rv, i, n_revents = 0;
- u32 sid;
+ vls_handle_t vlsh;
vcl_poll_t *vp;
- double wait_for_time;
+ double max_time;
- LDBG (3, "fds %p, nfds %d, timeout %d", fds, nfds, timeout);
+ LDBG (3, "fds %p, nfds %ld, timeout %d", fds, nfds, timeout);
- if (timeout >= 0)
- wait_for_time = (f64) timeout / 1000;
- else
- wait_for_time = -1;
+ if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
+ clib_time_init (&ldpw->clib_time);
+
+ max_time = (timeout >= 0) ? (f64) timeout / 1000 : 0;
+ max_time += clib_time_now (&ldpw->clib_time);
for (i = 0; i < nfds; i++)
{
if (fds[i].fd < 0)
continue;
- LDBG (3, "fds[%d] fd %d (0x%0x) events = 0x%x revents = 0x%x",
- i, fds[i].fd, fds[i].fd, fds[i].events, fds[i].revents);
-
- sid = ldp_sid_from_fd (fds[i].fd);
- if (sid != INVALID_SESSION_ID)
+ vlsh = ldp_fd_to_vlsh (fds[i].fd);
+ if (vlsh != VLS_INVALID_HANDLE)
{
fds[i].fd = -fds[i].fd;
vec_add2 (ldpw->vcl_poll, vp, 1);
vp->fds_ndx = i;
- vp->sid = sid;
+ vp->sh = vlsh_to_sh (vlsh);
vp->events = fds[i].events;
#ifdef __USE_XOPEN2K
if (fds[i].events & POLLRDNORM)
{
if (vec_len (ldpw->vcl_poll))
{
- func_str = "vppcom_poll";
-
- LDBG (3, "calling %s(): vcl_poll %p, n_sids %u (0x%x): "
- "n_libc_fds %u", func_str, ldpw->vcl_poll,
- vec_len (ldpw->vcl_poll), vec_len (ldpw->vcl_poll),
- vec_len (ldpw->libc_poll));
-
rv = vppcom_poll (ldpw->vcl_poll, vec_len (ldpw->vcl_poll), 0);
if (rv < 0)
{
if (vec_len (ldpw->libc_poll))
{
- func_str = "libc_poll";
-
- LDBG (3, "calling %s(): fds %p, nfds %u: n_sids %u",
- fds, nfds, vec_len (ldpw->vcl_poll));
-
rv = libc_poll (ldpw->libc_poll, vec_len (ldpw->libc_poll), 0);
if (rv < 0)
goto done;
goto done;
}
}
- while ((wait_for_time == -1) ||
- (clib_time_now (&ldpw->clib_time) < wait_for_time));
+ while ((timeout < 0) || (clib_time_now (&ldpw->clib_time) < max_time));
rv = 0;
done:
vec_reset_length (ldpw->libc_poll_idxs);
vec_reset_length (ldpw->libc_poll);
- if (LDP_DEBUG > 3)
- {
- if (rv < 0)
- {
- int errno_val = errno;
- perror (func_str);
- clib_warning ("LDP<%d>: ERROR: %s() failed! "
- "rv %d, errno = %d", getpid (),
- func_str, rv, errno_val);
- errno = errno_val;
- }
- else
- {
- clib_warning ("LDP<%d>: returning %d (0x%x): n_sids %u, "
- "n_libc_fds %d", getpid (), rv, rv,
- vec_len (ldpw->vcl_poll), vec_len (ldpw->libc_poll));
-
- for (i = 0; i < nfds; i++)
- {
- if (fds[i].fd >= 0)
- {
- if (LDP_DEBUG > 3)
- clib_warning ("LDP<%d>: fds[%d].fd %d (0x%0x), "
- ".events = 0x%x, .revents = 0x%x",
- getpid (), i, fds[i].fd, fds[i].fd,
- fds[i].events, fds[i].revents);
- }
- }
- }
- }
-
return rv;
}
-#ifdef USE_GNU
+#ifdef _GNU_SOURCE
int
ppoll (struct pollfd *fds, nfds_t nfds,
const struct timespec *timeout, const sigset_t * sigmask)
{
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
clib_warning ("LDP<%d>: LDP-TBD", getpid ());
errno = ENOSYS;
{
swrap_constructor ();
if (ldp_init () != 0)
- fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
- getpid ());
+ {
+ fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
+ getpid ());
+ _exit (1);
+ }
else if (LDP_DEBUG > 0)
clib_warning ("LDP<%d>: LDP constructor: done!\n", getpid ());
}
void
ldp_destructor (void)
{
- swrap_destructor ();
- if (ldp->init)
- ldp->init = 0;
+ /*
+ swrap_destructor ();
+ if (ldp->init)
+ ldp->init = 0;
+ */
/* Don't use clib_warning() here because that calls writev()
* which will call ldp_init().
*/
if (LDP_DEBUG > 0)
- printf ("%s:%d: LDP<%d>: LDP destructor: done!\n",
- __func__, __LINE__, getpid ());
+ fprintf (stderr, "%s:%d: LDP<%d>: LDP destructor: done!\n",
+ __func__, __LINE__, getpid ());
}