aboutsummaryrefslogtreecommitdiffstats
path: root/src/vcl
diff options
context:
space:
mode:
Diffstat (limited to 'src/vcl')
-rw-r--r--src/vcl/ldp.c105
-rw-r--r--src/vcl/vcl_bapi.c130
-rw-r--r--src/vcl/vcl_private.h19
-rw-r--r--src/vcl/vppcom.c39
-rw-r--r--src/vcl/vppcom.h15
5 files changed, 172 insertions, 136 deletions
diff --git a/src/vcl/ldp.c b/src/vcl/ldp.c
index 98ed4a9b1ab..b72c0c54acd 100644
--- a/src/vcl/ldp.c
+++ b/src/vcl/ldp.c
@@ -100,10 +100,15 @@ typedef struct
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
@@ -121,6 +126,7 @@ static ldp_main_t ldp_main = {
.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;
@@ -902,68 +908,71 @@ pselect (int nfds, fd_set * __restrict readfds,
/* 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)
{
@@ -999,10 +1008,8 @@ socket (int domain, int type, int protocol)
{
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);
}
diff --git a/src/vcl/vcl_bapi.c b/src/vcl/vcl_bapi.c
index 8e24bfeee0c..7d241624d01 100644
--- a/src/vcl/vcl_bapi.c
+++ b/src/vcl/vcl_bapi.c
@@ -244,41 +244,39 @@ failed:
}
static void
- vl_api_application_tls_cert_add_reply_t_handler
- (vl_api_application_tls_cert_add_reply_t * mp)
+vl_api_app_add_cert_key_pair_reply_t_handler (
+ vl_api_app_add_cert_key_pair_reply_t *mp)
{
vcl_worker_t *wrk = vcl_worker_get_current ();
if (mp->retval)
{
- VDBG (0, "add cert failed: %U", format_api_error, ntohl (mp->retval));
- wrk->bapi_app_state = STATE_APP_FAILED;
+ VDBG (0, "Adding cert and key failed: %U", format_api_error,
+ ntohl (mp->retval));
return;
}
+ wrk->bapi_return = clib_net_to_host_u32 (mp->index);
wrk->bapi_app_state = STATE_APP_READY;
}
static void
- vl_api_application_tls_key_add_reply_t_handler
- (vl_api_application_tls_key_add_reply_t * mp)
+vl_api_app_del_cert_key_pair_reply_t_handler (
+ vl_api_app_del_cert_key_pair_reply_t *mp)
{
- vcl_worker_t *wrk = vcl_worker_get_current ();
-
if (mp->retval)
{
- VDBG (0, "add key failed: %U", format_api_error, ntohl (mp->retval));
- wrk->bapi_app_state = STATE_APP_FAILED;
+ VDBG (0, "Deleting cert and key failed: %U", format_api_error,
+ ntohl (mp->retval));
return;
}
- wrk->bapi_app_state = STATE_APP_READY;
}
-#define foreach_sock_msg \
-_(SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply) \
-_(APP_ATTACH_REPLY, app_attach_reply) \
-_(APPLICATION_TLS_CERT_ADD_REPLY, application_tls_cert_add_reply) \
-_(APPLICATION_TLS_KEY_ADD_REPLY, application_tls_key_add_reply) \
-_(APP_WORKER_ADD_DEL_REPLY, app_worker_add_del_reply) \
+#define foreach_sock_msg \
+ _ (SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply) \
+ _ (APP_ATTACH_REPLY, app_attach_reply) \
+ _ (APP_ADD_CERT_KEY_PAIR_REPLY, app_add_cert_key_pair_reply) \
+ _ (APP_DEL_CERT_KEY_PAIR_REPLY, app_del_cert_key_pair_reply) \
+ _ (APP_WORKER_ADD_DEL_REPLY, app_worker_add_del_reply)
static void
vcl_bapi_hookup (void)
@@ -408,38 +406,41 @@ vcl_bapi_send_child_worker_del (vcl_worker_t * child_wrk)
vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & mp);
}
-void
-vcl_bapi_send_application_tls_cert_add (vcl_session_t * session, char *cert,
- u32 cert_len)
+static void
+vcl_bapi_send_app_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair)
{
vcl_worker_t *wrk = vcl_worker_get_current ();
- vl_api_application_tls_cert_add_t *cert_mp;
-
- cert_mp = vl_msg_api_alloc (sizeof (*cert_mp) + cert_len);
- clib_memset (cert_mp, 0, sizeof (*cert_mp));
- cert_mp->_vl_msg_id = ntohs (VL_API_APPLICATION_TLS_CERT_ADD);
- cert_mp->client_index = wrk->api_client_handle;
- cert_mp->context = session->session_index;
- cert_mp->cert_len = clib_host_to_net_u16 (cert_len);
- clib_memcpy_fast (cert_mp->cert, cert, cert_len);
- vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & cert_mp);
+ u32 cert_len = test_srv_crt_rsa_len;
+ u32 key_len = test_srv_key_rsa_len;
+ vl_api_app_add_cert_key_pair_t *bmp;
+
+ bmp = vl_msg_api_alloc (sizeof (*bmp) + cert_len + key_len);
+ clib_memset (bmp, 0, sizeof (*bmp) + cert_len + key_len);
+
+ bmp->_vl_msg_id = ntohs (VL_API_APP_ADD_CERT_KEY_PAIR);
+ bmp->client_index = wrk->api_client_handle;
+ bmp->context = wrk->wrk_index;
+ bmp->cert_len = clib_host_to_net_u16 (cert_len);
+ bmp->certkey_len = clib_host_to_net_u16 (key_len + cert_len);
+ clib_memcpy_fast (bmp->certkey, test_srv_crt_rsa, cert_len);
+ clib_memcpy_fast (bmp->certkey + cert_len, test_srv_key_rsa, key_len);
+
+ vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) &bmp);
}
-void
-vcl_bapi_send_application_tls_key_add (vcl_session_t * session, char *key,
- u32 key_len)
+static void
+vcl_bapi_send_app_del_cert_key_pair (u32 ckpair_index)
{
vcl_worker_t *wrk = vcl_worker_get_current ();
- vl_api_application_tls_key_add_t *key_mp;
-
- key_mp = vl_msg_api_alloc (sizeof (*key_mp) + key_len);
- clib_memset (key_mp, 0, sizeof (*key_mp));
- key_mp->_vl_msg_id = ntohs (VL_API_APPLICATION_TLS_KEY_ADD);
- key_mp->client_index = wrk->api_client_handle;
- key_mp->context = session->session_index;
- key_mp->key_len = clib_host_to_net_u16 (key_len);
- clib_memcpy_fast (key_mp->key, key, key_len);
- vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & key_mp);
+ vl_api_app_del_cert_key_pair_t *bmp;
+ bmp = vl_msg_api_alloc (sizeof (*bmp));
+ clib_memset (bmp, 0, sizeof (*bmp));
+
+ bmp->_vl_msg_id = ntohs (VL_API_APP_DEL_CERT_KEY_PAIR);
+ bmp->client_index = wrk->api_client_handle;
+ bmp->context = wrk->wrk_index;
+ bmp->index = clib_host_to_net_u32 (ckpair_index);
+ vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) &bmp);
}
u32
@@ -706,48 +707,27 @@ vcl_bapi_recv_fds (vcl_worker_t * wrk, int *fds, int n_fds)
}
int
-vppcom_session_tls_add_cert (uint32_t session_handle, char *cert,
- uint32_t cert_len)
+vcl_bapi_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair)
{
-
vcl_worker_t *wrk = vcl_worker_get_current ();
- vcl_session_t *session = 0;
- session = vcl_session_get_w_handle (wrk, session_handle);
- if (!session)
- return VPPCOM_EBADFD;
+ if (ckpair->key_len == 0 || ckpair->key_len == ~0)
+ return VPPCOM_EINVAL;
- if (cert_len == 0 || cert_len == ~0)
- return VPPCOM_EBADFD;
-
- /*
- * Send listen request to vpp and wait for reply
- */
- vcl_bapi_send_application_tls_cert_add (session, cert, cert_len);
+ vcl_bapi_send_app_add_cert_key_pair (ckpair);
wrk->bapi_app_state = STATE_APP_ADDING_TLS_DATA;
vcl_bapi_wait_for_wrk_state_change (STATE_APP_READY);
- return VPPCOM_OK;
+ if (wrk->bapi_app_state == STATE_APP_READY)
+ return wrk->bapi_return;
+ return VPPCOM_EFAULT;
}
int
-vppcom_session_tls_add_key (uint32_t session_handle, char *key,
- uint32_t key_len)
+vcl_bapi_del_cert_key_pair (u32 ckpair_index)
{
-
- vcl_worker_t *wrk = vcl_worker_get_current ();
- vcl_session_t *session = 0;
-
- session = vcl_session_get_w_handle (wrk, session_handle);
- if (!session)
- return VPPCOM_EBADFD;
-
- if (key_len == 0 || key_len == ~0)
- return VPPCOM_EBADFD;
-
- vcl_bapi_send_application_tls_key_add (session, key, key_len);
- wrk->bapi_app_state = STATE_APP_ADDING_TLS_DATA;
- vcl_bapi_wait_for_wrk_state_change (STATE_APP_READY);
- return VPPCOM_OK;
+ /* Don't wait for reply */
+ vcl_bapi_send_app_del_cert_key_pair (ckpair_index);
+ return 0;
}
int
diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h
index 0aa2fc10fa0..7104adc4452 100644
--- a/src/vcl/vcl_private.h
+++ b/src/vcl/vcl_private.h
@@ -154,12 +154,13 @@ typedef struct vcl_session_
vcl_session_msg_t *accept_evts_fifo;
u64 vpp_handle;
+ u64 parent_handle;
u32 listener_index; /**< index of parent listener (if any) */
int n_accepted_sessions; /**< sessions accepted by this listener */
+ vppcom_epoll_t vep;
u32 attributes; /**< see @ref vppcom_session_attr_t */
- u64 parent_handle;
int libc_epfd;
- vppcom_epoll_t vep;
+ u32 ckpair_index;
u32 sndbuf_size; // VPP-TBD: Hack until support setsockopt(SO_SNDBUF)
u32 rcvbuf_size; // VPP-TBD: Hack until support setsockopt(SO_RCVBUF)
@@ -287,6 +288,7 @@ typedef struct vcl_worker_
/* State of the connection, shared between msg RX thread and main thread */
volatile vcl_bapi_app_state_t bapi_app_state;
+ volatile uword bapi_return;
/** vcl needs next epoll_create to go to libc_epoll */
u8 vcl_needs_real_epoll;
@@ -536,6 +538,13 @@ vcl_session_is_cl (vcl_session_t * s)
}
static inline u8
+vcl_session_has_crypto (vcl_session_t *s)
+{
+ return (s->session_type == VPPCOM_PROTO_TLS ||
+ s->session_type == VPPCOM_PROTO_QUIC);
+}
+
+static inline u8
vcl_session_is_ready (vcl_session_t * s)
{
return (s->session_state == VCL_STATE_READY
@@ -699,10 +708,8 @@ int vcl_bapi_app_worker_add (void);
void vcl_bapi_app_worker_del (vcl_worker_t * wrk);
void vcl_bapi_disconnect_from_vpp (void);
int vcl_bapi_recv_fds (vcl_worker_t * wrk, int *fds, int n_fds);
-void vcl_bapi_send_application_tls_cert_add (vcl_session_t * session,
- char *cert, u32 cert_len);
-void vcl_bapi_send_application_tls_key_add (vcl_session_t * session,
- char *key, u32 key_len);
+int vcl_bapi_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair);
+int vcl_bapi_del_cert_key_pair (u32 ckpair_index);
u32 vcl_bapi_max_nsid_len (void);
int vcl_bapi_worker_set (void);
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c
index dbb2cd59a3b..412b6a4b995 100644
--- a/src/vcl/vppcom.c
+++ b/src/vcl/vppcom.c
@@ -182,6 +182,7 @@ vcl_send_session_listen (vcl_worker_t * wrk, vcl_session_t * s)
clib_memcpy_fast (&mp->ip, &s->transport.lcl_ip, sizeof (mp->ip));
mp->port = s->transport.lcl_port;
mp->proto = s->session_type;
+ mp->ckpair_index = s->ckpair_index;
if (s->flags & VCL_SESSION_F_CONNECTED)
mp->flags = TRANSPORT_CFG_F_CONNECTED;
app_send_ctrl_evt_to_vpp (mq, app_evt);
@@ -208,6 +209,7 @@ vcl_send_session_connect (vcl_worker_t * wrk, vcl_session_t * s)
mp->port = s->transport.rmt_port;
mp->lcl_port = s->transport.lcl_port;
mp->proto = s->session_type;
+ mp->ckpair_index = s->ckpair_index;
if (s->flags & VCL_SESSION_F_CONNECTED)
mp->flags |= TRANSPORT_CFG_F_CONNECTED;
app_send_ctrl_evt_to_vpp (mq, app_evt);
@@ -1282,6 +1284,7 @@ vppcom_session_create (u8 proto, u8 is_nonblocking)
session->session_type = proto;
session->session_state = VCL_STATE_CLOSED;
session->vpp_handle = ~0;
+ session->ckpair_index = ~0;
session->is_dgram = vcl_proto_is_dgram (proto);
if (is_nonblocking)
@@ -3082,10 +3085,10 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op,
void *buffer, uint32_t * buflen)
{
vcl_worker_t *wrk = vcl_worker_get_current ();
- vcl_session_t *session;
- int rv = VPPCOM_OK;
u32 *flags = buffer, tmp_flags = 0;
vppcom_endpt_t *ep = buffer;
+ vcl_session_t *session;
+ int rv = VPPCOM_OK;
session = vcl_session_get_w_handle (wrk, session_handle);
if (!session)
@@ -3633,6 +3636,16 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op,
session->flags |= VCL_SESSION_F_CONNECTED;
break;
+ case VPPCOM_ATTR_SET_CKPAIR:
+ if (!(buffer && buflen && (*buflen == sizeof (int))) ||
+ !vcl_session_has_crypto (session))
+ {
+ rv = VPPCOM_EINVAL;
+ break;
+ }
+ session->ckpair_index = *(uint32_t *) buffer;
+ break;
+
default:
rv = VPPCOM_EINVAL;
break;
@@ -4012,6 +4025,28 @@ vppcom_retval_str (int retval)
return st;
}
+int
+vppcom_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair)
+{
+ if (vcm->cfg.vpp_app_socket_api)
+ {
+ clib_warning ("not supported");
+ return VPPCOM_EINVAL;
+ }
+ return vcl_bapi_add_cert_key_pair (ckpair);
+}
+
+int
+vppcom_del_cert_key_pair (uint32_t ckpair_index)
+{
+ if (vcm->cfg.vpp_app_socket_api)
+ {
+ clib_warning ("not supported");
+ return VPPCOM_EINVAL;
+ }
+ return vcl_bapi_del_cert_key_pair (ckpair_index);
+}
+
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/src/vcl/vppcom.h b/src/vcl/vppcom.h
index 09303008870..77be8061159 100644
--- a/src/vcl/vppcom.h
+++ b/src/vcl/vppcom.h
@@ -71,6 +71,14 @@ typedef struct vppcom_endpt_t_
typedef uint32_t vcl_session_handle_t;
+typedef struct vppcom_cert_key_pair_
+{
+ char *cert;
+ char *key;
+ uint32_t cert_len;
+ uint32_t key_len;
+} vppcom_cert_key_pair_t;
+
typedef enum
{
VPPCOM_OK = 0,
@@ -129,6 +137,7 @@ typedef enum
VPPCOM_ATTR_SET_SHUT,
VPPCOM_ATTR_GET_SHUT,
VPPCOM_ATTR_SET_CONNECTED,
+ VPPCOM_ATTR_SET_CKPAIR,
} vppcom_attr_op_t;
typedef struct _vcl_poll
@@ -204,10 +213,8 @@ extern int vppcom_session_read_segments (uint32_t session_handle,
uint32_t max_bytes);
extern void vppcom_session_free_segments (uint32_t session_handle,
uint32_t n_bytes);
-extern int vppcom_session_tls_add_cert (uint32_t session_handle, char *cert,
- uint32_t cert_len);
-extern int vppcom_session_tls_add_key (uint32_t session_handle, char *key,
- uint32_t key_len);
+extern int vppcom_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair);
+extern int vppcom_del_cert_key_pair (uint32_t ckpair_index);
extern int vppcom_unformat_proto (uint8_t * proto, char *proto_str);
extern int vppcom_session_is_connectable_listener (uint32_t session_handle);
extern int vppcom_session_listener (uint32_t session_handle);