u32 vlsh_bit_val;
u32 vlsh_bit_mask;
u32 debug;
- u8 transparent_tls;
/** 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
if (ldp->debug > _lvl) \
{ \
int errno_saved = errno; \
- fprintf (stderr, "ldp<%d>: " _fmt, getpid(), ##_args); \
+ fprintf (stderr, "ldp<%d>: " _fmt "\n", getpid(), ##_args); \
errno = errno_saved; \
}
.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;
pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
}
-static inline int
+static int
ldp_init (void)
{
ldp_worker_ctx_t *ldpw;
int rv;
- if (PREDICT_TRUE (ldp->init))
- return 0;
+ ASSERT (!ldp->init);
ldp->init = 1;
ldp->vcl_needs_real_epoll = 1;
}
/* *INDENT-OFF* */
- pool_foreach (ldpw, ldp->workers, ({
+ pool_foreach (ldpw, ldp->workers) {
clib_memset (&ldpw->clib_time, 0, sizeof (ldpw->clib_time));
- }));
+ }
/* *INDENT-ON* */
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)
{
vls_handle_t vlsh;
int rv, epfd;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
vls_handle_t vlsh;
ssize_t size;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
vls_handle_t vlsh;
ssize_t size = 0;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
vls_handle_t vlsh;
ssize_t size = 0;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
vls_handle_t vlsh;
int i, rv = 0;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
va_list ap;
int rv;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
va_start (ap, cmd);
rv = fcntl_internal (fd, cmd, ap);
va_list ap;
int rv;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
va_start (ap, cmd);
rv = fcntl_internal (fd, cmd, ap);
va_list ap;
int rv;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
va_start (ap, cmd);
memset (original, 0, n_bytes);
/* *INDENT-OFF* */
- clib_bitmap_foreach (fd, *resultb, ({
+ clib_bitmap_foreach (fd, *resultb) {
if (fd > nfds)
break;
vlsh = ldp_fd_to_vlsh (fd);
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;
return 0;
/* *INDENT-OFF* */
- clib_bitmap_foreach (si, vclb, ({
+ clib_bitmap_foreach (si, vclb) {
vlsh = vls_session_index_to_vlsh (si);
ASSERT (vlsh != VLS_INVALID_HANDLE);
fd = ldp_vlsh_to_fd (vlsh);
return -1;
}
FD_SET (fd, libcb);
- }));
+ }
/* *INDENT-ON* */
return 0;
return;
/* *INDENT-OFF* */
- clib_bitmap_foreach (fd, result, ({
+ clib_bitmap_foreach (fd, result)
FD_SET ((int)fd, libcb);
- }));
/* *INDENT-ON* */
}
/* If transparent TLS mode is turned on, then ldp will load key and cert.
*/
static int
-load_tls_cert (vls_handle_t vlsh)
+load_cert_key_pair (void)
{
- char *env_var_str = getenv (LDP_ENV_TLS_CERT);
- char inbuf[4096];
- char *tls_cert;
- int cert_size;
+ 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 (env_var_str)
- {
- fp = fopen (env_var_str, "r");
- if (fp == NULL)
- {
- LDBG (0, "ERROR: failed to open cert file %s \n", env_var_str);
- return -1;
- }
- cert_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp);
- tls_cert = inbuf;
- vppcom_session_tls_add_cert (vlsh_to_session_index (vlsh), tls_cert,
- cert_size);
- fclose (fp);
- }
- else
+ if (!cert_str || !key_str)
{
LDBG (0, "ERROR: failed to read LDP environment %s\n",
LDP_ENV_TLS_CERT);
return -1;
}
- return 0;
-}
-static int
-load_tls_key (vls_handle_t vlsh)
-{
- char *env_var_str = getenv (LDP_ENV_TLS_KEY);
- char inbuf[4096];
- char *tls_key;
- int key_size;
- FILE *fp;
+ 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);
- if (env_var_str)
+ fp = fopen (key_str, "r");
+ if (fp == NULL)
{
- fp = fopen (env_var_str, "r");
- if (fp == NULL)
- {
- LDBG (0, "ERROR: failed to open key file %s \n", env_var_str);
- return -1;
- }
- key_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp);
- tls_key = inbuf;
- vppcom_session_tls_add_key (vlsh_to_session_index (vlsh), tls_key,
- key_size);
- fclose (fp);
+ LDBG (0, "ERROR: failed to open key file %s \n", key_str);
+ return -1;
}
- else
+ 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 read LDP environment %s\n", LDP_ENV_TLS_KEY);
+ 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 vppcom_session_attr (vlsh_to_session_index (vlsh),
+ VPPCOM_ATTR_SET_CKPAIR, &ldp->ckpair_index,
+ &ckp_len);
+}
+
int
socket (int domain, int type, int protocol)
{
u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
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)))
{
if (ldp->transparent_tls)
{
- if (load_tls_cert (vlsh) < 0 || load_tls_key (vlsh) < 0)
- {
- return -1;
- }
+ if (assign_cert_key_pair (vlsh) < 0)
+ return -1;
}
rv = ldp_vlsh_to_fd (vlsh);
}
{
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)))
vls_handle_t vlsh;
int rv;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
int rv = 0;
int sa_len, copy_len;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
if (addr && len && ep)
{
vls_handle_t vlsh;
int rv;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
vls_handle_t vlsh;
int rv;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
if (!addr)
{
vls_handle_t vlsh;
int rv;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
vls_handle_t vlsh = ldp_fd_to_vlsh (fd);
ssize_t size;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
if (vlsh != VLS_INVALID_HANDLE)
{
vls_handle_t vlsh;
ssize_t size = 0;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (out_fd);
if (vlsh != VLS_INVALID_HANDLE)
vls_handle_t vlsh;
ssize_t size;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
vls_handle_t vlsh;
ssize_t size;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != INVALID_SESSION_ID)
vls_handle_t vlsh;
ssize_t size;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
vls_handle_t vlsh;
ssize_t size;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
const char *func_str;
u32 sh = ldp_fd_to_vlsh (fd);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
if (sh != INVALID_SESSION_ID)
{
vls_handle_t vlsh;
ssize_t size;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
const char *func_str;
u32 sh = ldp_fd_to_vlsh (fd);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
if (sh != INVALID_SESSION_ID)
{
vls_handle_t vlsh;
int rv;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
case SO_REUSEADDR:
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:
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:
rv = vls_attr (vlsh, VPPCOM_ATTR_GET_ERROR, optval, optlen);
break;
vls_handle_t vlsh;
int rv;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
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:
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);
vls_handle_t vlsh;
int rv;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
vls_handle_t listen_vlsh, accept_vlsh;
int rv;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
listen_vlsh = ldp_fd_to_vlsh (listen_fd);
if (listen_vlsh != VLS_INVALID_HANDLE)
int rv = 0, flags;
u32 flags_len = sizeof (flags);
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
if (flags == SHUT_RDWR)
rv = close (fd);
+ else if (flags == SHUT_WR)
+ rv = vls_shutdown (vlsh);
}
else
{
vls_handle_t vlsh;
int rv;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
if (ldp->vcl_needs_real_epoll || vls_use_real_epoll ())
{
vls_handle_t vep_vlsh, vlsh;
int rv;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
vep_vlsh = ldp_fd_to_vlsh (epfd);
if (PREDICT_FALSE (vep_vlsh == VLS_INVALID_HANDLE))
int libc_epfd, rv = 0;
vls_handle_t ep_vlsh;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
if (PREDICT_FALSE (!events || (timeout < -1)))
{
int libc_epfd, rv = 0, num_ev;
vls_handle_t ep_vlsh;
- if ((errno = -ldp_init ()))
- return -1;
+ ldp_init_check ();
if (PREDICT_FALSE (!events || (timeout < -1)))
{
ldpw->mq_epfd_added = 1;
}
- rv = vls_epoll_wait (ep_vlsh, events, maxevents, 0);
+ /* Request to only drain unhandled to prevent libc_epoll_wait starved */
+ rv = vls_epoll_wait (ep_vlsh, events, maxevents, -2);
if (rv > 0)
goto done;
else if (PREDICT_FALSE (rv < 0))
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;