From a54b62d77794dee48510e7c128d3ab2fc90934b3 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Wed, 21 Apr 2021 09:05:56 -0700 Subject: [PATCH] vcl session: refactor passing of crypto context Pass tls/quic crypto context using extended config instead of bloating conect/listen messages. Type: refactor Signed-off-by: Florin Coras Change-Id: I0bc637ae310e6c31ef1e16847501dcb81453ee94 --- src/plugins/hs_apps/echo_client.c | 19 +++++++++- src/plugins/hs_apps/echo_server.c | 16 +++++++- src/plugins/hs_apps/http_server.c | 20 +++++++++- src/plugins/hs_apps/proxy.c | 34 +++++++++++++++-- src/plugins/hs_apps/sapi/vpp_echo_bapi.c | 61 ++++++++++++++++++++++++++++-- src/plugins/hs_apps/sapi/vpp_echo_common.h | 3 ++ src/plugins/http_static/static_server.c | 20 +++++++++- src/plugins/quic/quic.c | 23 ++++++++--- src/vcl/vcl_private.c | 15 ++++++++ src/vcl/vcl_private.h | 5 ++- src/vcl/vppcom.c | 15 ++++++-- src/vnet/session/application.c | 2 +- src/vnet/session/application_interface.c | 18 --------- src/vnet/session/application_interface.h | 29 +++++++------- src/vnet/session/session_node.c | 11 ------ src/vnet/session/session_types.h | 7 +--- src/vnet/session/transport_types.h | 19 +++++++++- src/vnet/tls/tls.c | 47 +++++++++++++++++------ 18 files changed, 278 insertions(+), 86 deletions(-) diff --git a/src/plugins/hs_apps/echo_client.c b/src/plugins/hs_apps/echo_client.c index 4680ae2f8d1..d641a9ec14e 100644 --- a/src/plugins/hs_apps/echo_client.c +++ b/src/plugins/hs_apps/echo_client.c @@ -718,6 +718,13 @@ echo_clients_start_tx_pthread (echo_client_main_t * ecm) return 0; } +static int +echo_client_transport_needs_crypto (transport_proto_t proto) +{ + return proto == TRANSPORT_PROTO_TLS || proto == TRANSPORT_PROTO_DTLS || + proto == TRANSPORT_PROTO_QUIC; +} + clib_error_t * echo_clients_connect (vlib_main_t * vm, u32 n_clients) { @@ -736,10 +743,18 @@ echo_clients_connect (vlib_main_t * vm, u32 n_clients) clib_memcpy (&a->sep_ext, &sep, sizeof (sep)); a->api_context = i; a->app_index = ecm->app_index; - a->sep_ext.ckpair_index = ecm->ckpair_index; + if (echo_client_transport_needs_crypto (a->sep_ext.transport_proto)) + { + session_endpoint_alloc_ext_cfg (&a->sep_ext, + TRANSPORT_ENDPT_EXT_CFG_CRYPTO); + a->sep_ext.ext_cfg->crypto.ckpair_index = ecm->ckpair_index; + } vlib_worker_thread_barrier_sync (vm); - if ((rv = vnet_connect (a))) + rv = vnet_connect (a); + if (a->sep_ext.ext_cfg) + clib_mem_free (a->sep_ext.ext_cfg); + if (rv) { vlib_worker_thread_barrier_release (vm); return clib_error_return (0, "connect returned: %d", rv); diff --git a/src/plugins/hs_apps/echo_server.c b/src/plugins/hs_apps/echo_server.c index 63150d5a8d8..b75a3667e83 100644 --- a/src/plugins/hs_apps/echo_server.c +++ b/src/plugins/hs_apps/echo_server.c @@ -384,6 +384,13 @@ echo_server_detach (void) return rv; } +static int +echo_client_transport_needs_crypto (transport_proto_t proto) +{ + return proto == TRANSPORT_PROTO_TLS || proto == TRANSPORT_PROTO_DTLS || + proto == TRANSPORT_PROTO_QUIC; +} + static int echo_server_listen () { @@ -398,7 +405,12 @@ echo_server_listen () return -1; } args->app_index = esm->app_index; - args->sep_ext.ckpair_index = esm->ckpair_index; + if (echo_client_transport_needs_crypto (args->sep_ext.transport_proto)) + { + session_endpoint_alloc_ext_cfg (&args->sep_ext, + TRANSPORT_ENDPT_EXT_CFG_CRYPTO); + args->sep_ext.ext_cfg->crypto.ckpair_index = esm->ckpair_index; + } if (args->sep_ext.transport_proto == TRANSPORT_PROTO_UDP) { @@ -407,6 +419,8 @@ echo_server_listen () rv = vnet_listen (args); esm->listener_handle = args->handle; + if (args->sep_ext.ext_cfg) + clib_mem_free (args->sep_ext.ext_cfg); return rv; } diff --git a/src/plugins/hs_apps/http_server.c b/src/plugins/hs_apps/http_server.c index 72e3f3230b1..34892b6bd4d 100644 --- a/src/plugins/hs_apps/http_server.c +++ b/src/plugins/hs_apps/http_server.c @@ -759,6 +759,13 @@ http_server_attach () return 0; } +static int +http_transport_needs_crypto (transport_proto_t proto) +{ + return proto == TRANSPORT_PROTO_TLS || proto == TRANSPORT_PROTO_DTLS || + proto == TRANSPORT_PROTO_QUIC; +} + static int http_server_listen () { @@ -766,6 +773,7 @@ http_server_listen () http_server_main_t *hsm = &http_server_main; vnet_listen_args_t _a, *a = &_a; char *uri = "tcp://0.0.0.0/80"; + int rv; clib_memset (a, 0, sizeof (*a)); a->app_index = hsm->app_index; @@ -777,9 +785,17 @@ http_server_listen () return -1; clib_memcpy (&a->sep_ext, &sep, sizeof (sep)); - a->sep_ext.ckpair_index = hsm->ckpair_index; + if (http_transport_needs_crypto (a->sep_ext.transport_proto)) + { + session_endpoint_alloc_ext_cfg (&a->sep_ext, + TRANSPORT_ENDPT_EXT_CFG_CRYPTO); + a->sep_ext.ext_cfg->crypto.ckpair_index = hsm->ckpair_index; + } - return vnet_listen (a); + rv = vnet_listen (a); + if (a->sep_ext.ext_cfg) + clib_mem_free (a->sep_ext.ext_cfg); + return rv; } static void diff --git a/src/plugins/hs_apps/proxy.c b/src/plugins/hs_apps/proxy.c index 000815813ce..1a49a0f1f3a 100644 --- a/src/plugins/hs_apps/proxy.c +++ b/src/plugins/hs_apps/proxy.c @@ -42,6 +42,8 @@ proxy_cb_fn (void *data, u32 data_len) a.app_index = pa->app_index; clib_memcpy (&a.sep_ext, &pa->sep, sizeof (pa->sep)); vnet_connect (&a); + if (a.sep_ext.ext_cfg) + clib_mem_free (a.sep_ext.ext_cfg); } static void @@ -50,6 +52,8 @@ proxy_call_main_thread (vnet_connect_args_t * a) if (vlib_get_thread_index () == 0) { vnet_connect (a); + if (a->sep_ext.ext_cfg) + clib_mem_free (a->sep_ext.ext_cfg); } else { @@ -282,6 +286,12 @@ proxy_add_segment_callback (u32 client_index, u64 segment_handle) return -1; } +static int +proxy_transport_needs_crypto (transport_proto_t proto) +{ + return proto == TRANSPORT_PROTO_TLS; +} + static int proxy_rx_callback (session_t * s) { @@ -353,9 +363,16 @@ proxy_rx_callback (session_t * s) clib_spinlock_unlock_if_init (&pm->sessions_lock); clib_memcpy (&a->sep_ext, &pm->client_sep, sizeof (pm->client_sep)); - a->sep_ext.ckpair_index = pm->ckpair_index; a->api_context = proxy_index; a->app_index = pm->active_open_app_index; + + if (proxy_transport_needs_crypto (a->sep.transport_proto)) + { + session_endpoint_alloc_ext_cfg (&a->sep_ext, + TRANSPORT_ENDPT_EXT_CFG_CRYPTO); + a->sep_ext.ext_cfg->crypto.ckpair_index = pm->ckpair_index; + } + proxy_call_main_thread (a); } @@ -697,13 +714,24 @@ proxy_server_listen () { proxy_main_t *pm = &proxy_main; vnet_listen_args_t _a, *a = &_a; + int rv; + clib_memset (a, 0, sizeof (*a)); a->app_index = pm->server_app_index; clib_memcpy (&a->sep_ext, &pm->server_sep, sizeof (pm->server_sep)); - a->sep_ext.ckpair_index = pm->ckpair_index; + if (proxy_transport_needs_crypto (a->sep.transport_proto)) + { + session_endpoint_alloc_ext_cfg (&a->sep_ext, + TRANSPORT_ENDPT_EXT_CFG_CRYPTO); + a->sep_ext.ext_cfg->crypto.ckpair_index = pm->ckpair_index; + } + + rv = vnet_listen (a); + if (a->sep_ext.ext_cfg) + clib_mem_free (a->sep_ext.ext_cfg); - return vnet_listen (a); + return rv; } static void diff --git a/src/plugins/hs_apps/sapi/vpp_echo_bapi.c b/src/plugins/hs_apps/sapi/vpp_echo_bapi.c index 0a0168b070e..7cf15eb1486 100644 --- a/src/plugins/hs_apps/sapi/vpp_echo_bapi.c +++ b/src/plugins/hs_apps/sapi/vpp_echo_bapi.c @@ -100,6 +100,31 @@ echo_send_del_cert_key (echo_main_t * em) vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp); } +static u8 +echo_transport_needs_crypto (transport_proto_t proto) +{ + return proto == TRANSPORT_PROTO_TLS || proto == TRANSPORT_PROTO_DTLS || + proto == TRANSPORT_PROTO_QUIC; +} + +static void +echo_msg_add_crypto_ext_config (echo_main_t *em, uword *offset) +{ + transport_endpt_ext_cfg_t cfg; + svm_fifo_chunk_t *c; + + c = echo_segment_alloc_chunk (ECHO_MQ_SEG_HANDLE, 0, sizeof (cfg), offset); + if (!c) + return; + + memset (&cfg, 0, sizeof (cfg)); + cfg.type = TRANSPORT_ENDPT_EXT_CFG_CRYPTO; + cfg.len = sizeof (cfg); + cfg.crypto.ckpair_index = em->ckpair_index; + cfg.crypto.crypto_engine = em->crypto_engine; + clib_memcpy_fast (c->data, &cfg, cfg.len); +} + void echo_send_listen (echo_main_t * em, ip46_address_t * ip) { @@ -117,8 +142,8 @@ echo_send_listen (echo_main_t * em, ip46_address_t * ip) clib_memcpy_fast (&mp->ip, ip, sizeof (mp->ip)); mp->port = em->uri_elts.port; mp->proto = em->uri_elts.transport_proto; - mp->ckpair_index = em->ckpair_index; - mp->crypto_engine = em->crypto_engine; + if (echo_transport_needs_crypto (mp->proto)) + echo_msg_add_crypto_ext_config (em, &mp->ext_config); app_send_ctrl_evt_to_vpp (mq, app_evt); } @@ -163,8 +188,8 @@ echo_send_connect (echo_main_t * em, void *args) mp->port = em->uri_elts.port; mp->proto = em->uri_elts.transport_proto; mp->parent_handle = a->parent_session_handle; - mp->ckpair_index = em->ckpair_index; - mp->crypto_engine = em->crypto_engine; + if (echo_transport_needs_crypto (mp->proto)) + echo_msg_add_crypto_ext_config (em, &mp->ext_config); mp->flags = em->connect_flag; app_send_ctrl_evt_to_vpp (mq, app_evt); } @@ -332,6 +357,34 @@ echo_segment_attach_mq (uword segment_handle, uword mq_offset, u32 mq_index, return 0; } +svm_fifo_chunk_t * +echo_segment_alloc_chunk (uword segment_handle, u32 slice_index, u32 size, + uword *offset) +{ + echo_main_t *em = &echo_main; + svm_fifo_chunk_t *c; + fifo_segment_t *fs; + u32 fs_index; + + fs_index = echo_segment_lookup (segment_handle); + if (fs_index == (u32) ~0) + { + ECHO_LOG (0, "ERROR: mq segment %lx for is not attached!", + segment_handle); + return 0; + } + + clib_spinlock_lock (&em->segment_handles_lock); + + fs = fifo_segment_get_segment (&em->segment_main, fs_index); + c = fifo_segment_alloc_chunk_w_slice (fs, slice_index, size); + *offset = fifo_segment_chunk_offset (fs, c); + + clib_spinlock_unlock (&em->segment_handles_lock); + + return c; +} + /* * * Binary API callbacks diff --git a/src/plugins/hs_apps/sapi/vpp_echo_common.h b/src/plugins/hs_apps/sapi/vpp_echo_common.h index dc5f7dfb9b5..4760f3b06e3 100644 --- a/src/plugins/hs_apps/sapi/vpp_echo_common.h +++ b/src/plugins/hs_apps/sapi/vpp_echo_common.h @@ -448,6 +448,9 @@ int echo_attach_session (uword segment_handle, uword rxf_offset, uword mq_offset, uword txf_offset, echo_session_t *s); int echo_segment_attach_mq (uword segment_handle, uword mq_offset, u32 mq_index, svm_msg_q_t **mq); +svm_fifo_chunk_t *echo_segment_alloc_chunk (uword segment_handle, + u32 slice_index, u32 size, + uword *offset); /* Binary API */ diff --git a/src/plugins/http_static/static_server.c b/src/plugins/http_static/static_server.c index b354666f816..23860b083d8 100644 --- a/src/plugins/http_static/static_server.c +++ b/src/plugins/http_static/static_server.c @@ -1185,6 +1185,13 @@ http_static_server_attach () return 0; } +static int +http_static_transport_needs_crypto (transport_proto_t proto) +{ + return proto == TRANSPORT_PROTO_TLS || proto == TRANSPORT_PROTO_DTLS || + proto == TRANSPORT_PROTO_QUIC; +} + static int http_static_server_listen () { @@ -1192,6 +1199,7 @@ http_static_server_listen () session_endpoint_cfg_t sep = SESSION_ENDPOINT_CFG_NULL; vnet_listen_args_t _a, *a = &_a; char *uri = "tcp://0.0.0.0/80"; + int rv; clib_memset (a, 0, sizeof (*a)); a->app_index = hsm->app_index; @@ -1203,9 +1211,17 @@ http_static_server_listen () return -1; clib_memcpy (&a->sep_ext, &sep, sizeof (sep)); - a->sep_ext.ckpair_index = hsm->ckpair_index; + if (http_static_transport_needs_crypto (a->sep_ext.transport_proto)) + { + session_endpoint_alloc_ext_cfg (&a->sep_ext, + TRANSPORT_ENDPT_EXT_CFG_CRYPTO); + a->sep_ext.ext_cfg->crypto.ckpair_index = hsm->ckpair_index; + } - return vnet_listen (a); + rv = vnet_listen (a); + if (a->sep_ext.ext_cfg) + clib_mem_free (a->sep_ext.ext_cfg); + return rv; } static void diff --git a/src/plugins/quic/quic.c b/src/plugins/quic/quic.c index cf4d1470ffd..cf697278cb7 100644 --- a/src/plugins/quic/quic.c +++ b/src/plugins/quic/quic.c @@ -1304,6 +1304,7 @@ static int quic_connect_connection (session_endpoint_cfg_t * sep) { vnet_connect_args_t _cargs, *cargs = &_cargs; + transport_endpt_crypto_cfg_t *ccfg; quic_main_t *qm = &quic_main; quic_ctx_t *ctx; app_worker_t *app_wrk; @@ -1312,6 +1313,11 @@ quic_connect_connection (session_endpoint_cfg_t * sep) u32 thread_index = vlib_get_thread_index (); int error; + if (!sep->ext_cfg) + return -1; + + ccfg = &sep->ext_cfg->crypto; + clib_memset (cargs, 0, sizeof (*cargs)); ctx_index = quic_ctx_alloc (thread_index); ctx = quic_ctx_get (ctx_index, thread_index); @@ -1323,8 +1329,8 @@ quic_connect_connection (session_endpoint_cfg_t * sep) ctx->conn_state = QUIC_CONN_STATE_HANDSHAKE; ctx->client_opaque = sep->opaque; ctx->c_flags |= TRANSPORT_CONNECTION_F_NO_LOOKUP; - if (sep->hostname) - ctx->srv_hostname = format (0, "%v", sep->hostname); + if (ccfg->hostname[0]) + ctx->srv_hostname = format (0, "%s", ccfg->hostname); else /* needed by quic for crypto + determining client / server */ ctx->srv_hostname = format (0, "%U", format_ip46_address, @@ -1342,8 +1348,8 @@ quic_connect_connection (session_endpoint_cfg_t * sep) cargs->sep_ext.ns_index = app->ns_index; cargs->sep_ext.transport_flags = TRANSPORT_CFG_F_CONNECTED; - ctx->crypto_engine = sep->crypto_engine; - ctx->ckpair_index = sep->ckpair_index; + ctx->crypto_engine = ccfg->crypto_engine; + ctx->ckpair_index = ccfg->ckpair_index; if ((error = quic_acquire_crypto_context (ctx))) return error; @@ -1435,6 +1441,7 @@ static u32 quic_start_listen (u32 quic_listen_session_index, transport_endpoint_t * tep) { vnet_listen_args_t _bargs, *args = &_bargs; + transport_endpt_crypto_cfg_t *ccfg; quic_main_t *qm = &quic_main; session_handle_t udp_handle; session_endpoint_cfg_t *sep; @@ -1447,6 +1454,10 @@ quic_start_listen (u32 quic_listen_session_index, transport_endpoint_t * tep) int rv; sep = (session_endpoint_cfg_t *) tep; + if (!sep->ext_cfg) + return -1; + + ccfg = &sep->ext_cfg->crypto; app_wrk = app_worker_get (sep->app_wrk_index); /* We need to call this because we call app_worker_init_connected in * quic_accept_stream, which assumes the connect segment manager exists */ @@ -1483,8 +1494,8 @@ quic_start_listen (u32 quic_listen_session_index, transport_endpoint_t * tep) lctx->parent_app_id = app_wrk->app_index; lctx->udp_session_handle = udp_handle; lctx->c_s_index = quic_listen_session_index; - lctx->crypto_engine = sep->crypto_engine; - lctx->ckpair_index = sep->ckpair_index; + lctx->crypto_engine = ccfg->crypto_engine; + lctx->ckpair_index = ccfg->ckpair_index; if (quic_acquire_crypto_context (lctx)) return -1; diff --git a/src/vcl/vcl_private.c b/src/vcl/vcl_private.c index 721416b045a..464061cfb5a 100644 --- a/src/vcl/vcl_private.c +++ b/src/vcl/vcl_private.c @@ -315,6 +315,21 @@ vcl_session_write_ready (vcl_session_t * s) } } +int +vcl_session_alloc_ext_cfg (vcl_session_t *s, + transport_endpt_ext_cfg_type_t type) +{ + if (s->ext_config) + return -1; + + s->ext_config = clib_mem_alloc (sizeof (transport_endpt_ext_cfg_t)); + clib_memset (s->ext_config, 0, sizeof (*s->ext_config)); + s->ext_config->len = sizeof (*s->ext_config); + s->ext_config->type = type; + + return 0; +} + int vcl_segment_attach (u64 segment_handle, char *name, ssvm_segment_type_t type, int fd) diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h index 1da334a1da9..12504c51982 100644 --- a/src/vcl/vcl_private.h +++ b/src/vcl/vcl_private.h @@ -160,7 +160,6 @@ typedef struct vcl_session_ vppcom_epoll_t vep; u32 attributes; /**< see @ref vppcom_session_attr_t */ int libc_epfd; - u32 ckpair_index; u32 vrf; u32 sndbuf_size; // VPP-TBD: Hack until support setsockopt(SO_SNDBUF) @@ -389,6 +388,8 @@ vcl_session_free (vcl_worker_t * wrk, vcl_session_t * s) /* Debug level set to 1 to avoid debug messages while ldp is cleaning up */ VDBG (1, "session %u [0x%llx] removed", s->session_index, s->vpp_handle); vcl_session_detach_fifos (s); + if (s->ext_config) + clib_mem_free (s->ext_config); pool_put (wrk->sessions, s); } @@ -663,6 +664,8 @@ void vcl_segment_table_del (u64 segment_handle); int vcl_session_read_ready (vcl_session_t * session); int vcl_session_write_ready (vcl_session_t * session); +int vcl_session_alloc_ext_cfg (vcl_session_t *s, + transport_endpt_ext_cfg_type_t type); static inline vcl_worker_t * vcl_worker_get (u32 wrk_index) diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 1ece9db9940..a0f4338f902 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -193,7 +193,6 @@ 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; mp->vrf = s->vrf; if (s->flags & VCL_SESSION_F_CONNECTED) mp->flags = TRANSPORT_CFG_F_CONNECTED; @@ -228,7 +227,6 @@ 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; mp->vrf = s->vrf; if (s->flags & VCL_SESSION_F_CONNECTED) mp->flags |= TRANSPORT_CFG_F_CONNECTED; @@ -1374,7 +1372,6 @@ 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) @@ -3710,7 +3707,17 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op, rv = VPPCOM_EINVAL; break; } - session->ckpair_index = *(uint32_t *) buffer; + if (!session->ext_config) + { + vcl_session_alloc_ext_cfg (session, TRANSPORT_ENDPT_EXT_CFG_CRYPTO); + } + else if (session->ext_config->type != TRANSPORT_ENDPT_EXT_CFG_CRYPTO) + { + rv = VPPCOM_EINVAL; + break; + } + + session->ext_config->crypto.ckpair_index = *(uint32_t *) buffer; break; case VPPCOM_ATTR_SET_VRF: diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c index a93e4b9dbbf..56a514192af 100644 --- a/src/vnet/session/application.c +++ b/src/vnet/session/application.c @@ -615,7 +615,7 @@ app_rx_mqs_alloc (application_t *app) cfg->q_nitems = evt_q_length; cfg->ring_cfgs = rc; - eqs->ssvm.ssvm_size = svm_msg_q_size_to_alloc (cfg) * n_mqs + (16 << 10); + eqs->ssvm.ssvm_size = svm_msg_q_size_to_alloc (cfg) * n_mqs + (1 << 20); eqs->ssvm.name = format (0, "%s-rx-mqs-seg%c", app->name, 0); if (ssvm_server_init (&eqs->ssvm, SSVM_SEGMENT_MEMFD)) diff --git a/src/vnet/session/application_interface.c b/src/vnet/session/application_interface.c index a6d1a029f13..74f456a1eab 100644 --- a/src/vnet/session/application_interface.c +++ b/src/vnet/session/application_interface.c @@ -51,15 +51,6 @@ unformat_vnet_uri (unformat_input_t * input, va_list * args) sep->is_ip4 = 1; return 1; } - else if (unformat (input, "%U://[%s]%U/%d", unformat_transport_proto, - &transport_proto, &sep->hostname, unformat_ip4_address, - &sep->ip.ip4, &port)) - { - sep->transport_proto = transport_proto; - sep->port = clib_host_to_net_u16 (port); - sep->is_ip4 = 1; - return 1; - } else if (unformat (input, "%U://%U/%d", unformat_transport_proto, &transport_proto, unformat_ip6_address, &sep->ip.ip6, &port)) @@ -69,15 +60,6 @@ unformat_vnet_uri (unformat_input_t * input, va_list * args) sep->is_ip4 = 0; return 1; } - else if (unformat (input, "%U://[%s]%U/%d", unformat_transport_proto, - &transport_proto, &sep->hostname, unformat_ip6_address, - &sep->ip.ip6, &port)) - { - sep->transport_proto = transport_proto; - sep->port = clib_host_to_net_u16 (port); - sep->is_ip4 = 0; - return 1; - } else if (unformat (input, "%U://session/%lu", unformat_transport_proto, &transport_proto, &sep->parent_handle)) { diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h index be6c74c6529..ba148e287ad 100644 --- a/src/vnet/session/application_interface.h +++ b/src/vnet/session/application_interface.h @@ -314,8 +314,6 @@ typedef struct session_listen_msg_ u8 proto; u8 is_ip4; ip46_address_t ip; - u32 ckpair_index; - u8 crypto_engine; u8 flags; uword ext_config; } __clib_packed session_listen_msg_t; @@ -399,18 +397,7 @@ typedef struct session_connect_msg_ u32 ckpair_index; u8 crypto_engine; u8 flags; - union - { - struct - { - u8 hostname[16]; - u8 hostname_len; - } __clib_packed; - struct - { - uword ext_config; - } __clib_packed; - }; + uword ext_config; } __clib_packed session_connect_msg_t; STATIC_ASSERT (sizeof (session_connect_msg_t) <= SESSION_CTRL_MSG_MAX_SIZE, @@ -870,6 +857,20 @@ typedef struct app_sapi_msg_ }; } __clib_packed app_sapi_msg_t; +static inline void +session_endpoint_alloc_ext_cfg (session_endpoint_cfg_t *sep_ext, + transport_endpt_ext_cfg_type_t type) +{ + transport_endpt_ext_cfg_t *cfg; + u32 cfg_size; + + cfg_size = sizeof (transport_endpt_ext_cfg_t); + cfg = clib_mem_alloc (cfg_size); + clib_memset (cfg, 0, cfg_size); + cfg->type = type; + sep_ext->ext_cfg = cfg; +} + #endif /* __included_uri_h__ */ /* diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c index a4db02362d3..93ed7b7c3f2 100644 --- a/src/vnet/session/session_node.c +++ b/src/vnet/session/session_node.c @@ -78,8 +78,6 @@ session_mq_listen_handler (void *data) a->sep.fib_index = mp->vrf; a->sep.sw_if_index = ENDPOINT_INVALID_INDEX; a->sep.transport_proto = mp->proto; - a->sep_ext.ckpair_index = mp->ckpair_index; - a->sep_ext.crypto_engine = mp->crypto_engine; a->app_index = app->app_index; a->wrk_map_index = mp->wrk_index; a->sep_ext.transport_flags = mp->flags; @@ -151,14 +149,7 @@ session_mq_connect_handler (void *data) a->sep.peer.port = mp->lcl_port; a->sep.peer.sw_if_index = ENDPOINT_INVALID_INDEX; a->sep_ext.parent_handle = mp->parent_handle; - a->sep_ext.ckpair_index = mp->ckpair_index; - a->sep_ext.crypto_engine = mp->crypto_engine; a->sep_ext.transport_flags = mp->flags; - if (mp->hostname_len) - { - vec_validate (a->sep_ext.hostname, mp->hostname_len - 1); - clib_memcpy_fast (a->sep_ext.hostname, mp->hostname, mp->hostname_len); - } a->api_context = mp->context; a->app_index = app->app_index; a->wrk_map_index = mp->wrk_index; @@ -175,8 +166,6 @@ session_mq_connect_handler (void *data) if (mp->ext_config) session_mq_free_ext_config (app, mp->ext_config); - - vec_free (a->sep_ext.hostname); } static void diff --git a/src/vnet/session/session_types.h b/src/vnet/session/session_types.h index 148f100f512..9211df9e46d 100644 --- a/src/vnet/session/session_types.h +++ b/src/vnet/session/session_types.h @@ -44,10 +44,7 @@ typedef struct _session_endpoint_cfg u32 opaque; u32 ns_index; u8 original_tp; - u8 *hostname; u64 parent_handle; - u32 ckpair_index; - u8 crypto_engine; u8 flags; transport_endpt_ext_cfg_t *ext_cfg; } session_endpoint_cfg_t; @@ -83,8 +80,8 @@ typedef struct _session_endpoint_cfg .fib_index = ENDPOINT_INVALID_INDEX, .is_ip4 = 0, .port = 0, \ .peer = TRANSPORT_ENDPOINT_NULL, .transport_proto = 0, \ .app_wrk_index = ENDPOINT_INVALID_INDEX, \ - .opaque = ENDPOINT_INVALID_INDEX, .hostname = 0, \ - .parent_handle = SESSION_INVALID_HANDLE, .ckpair_index = 0, .ext_cfg = 0, \ + .opaque = ENDPOINT_INVALID_INDEX, \ + .parent_handle = SESSION_INVALID_HANDLE, .ext_cfg = 0, \ } #define session_endpoint_to_transport(_sep) ((transport_endpoint_t *)_sep) diff --git a/src/vnet/session/transport_types.h b/src/vnet/session/transport_types.h index 0041adb2c64..7ea8d5f0416 100644 --- a/src/vnet/session/transport_types.h +++ b/src/vnet/session/transport_types.h @@ -259,11 +259,28 @@ typedef struct transport_endpt_attr_ }; } transport_endpt_attr_t; +typedef enum transport_endpt_ext_cfg_type_ +{ + TRANSPORT_ENDPT_EXT_CFG_NONE, + TRANSPORT_ENDPT_EXT_CFG_CRYPTO, +} transport_endpt_ext_cfg_type_t; + +typedef struct transport_endpt_crypto_cfg_ +{ + u32 ckpair_index; + u8 crypto_engine; + u8 hostname[256]; /**< full domain len is 255 as per rfc 3986 */ +} transport_endpt_crypto_cfg_t; + typedef struct transport_endpt_ext_cfg_ { u16 type; u16 len; - u8 data[0]; + union + { + transport_endpt_crypto_cfg_t crypto; + u8 data[0]; + }; } transport_endpt_ext_cfg_t; typedef clib_bihash_24_8_t transport_endpoint_table_t; diff --git a/src/vnet/tls/tls.c b/src/vnet/tls/tls.c index a950f142932..808c151dac5 100644 --- a/src/vnet/tls/tls.c +++ b/src/vnet/tls/tls.c @@ -280,8 +280,15 @@ tls_ctx_parse_handle (u32 ctx_handle, u32 * ctx_index, u32 * engine_type) } static inline crypto_engine_type_t -tls_get_engine_type (crypto_engine_type_t preferred) +tls_get_engine_type (crypto_engine_type_t requested, + crypto_engine_type_t preferred) { + if (requested != CRYPTO_ENGINE_NONE) + { + if (tls_vfts[requested].ctx_alloc) + return requested; + return CRYPTO_ENGINE_NONE; + } if (!tls_vfts[preferred].ctx_alloc) return tls_get_available_engine (); return preferred; @@ -662,6 +669,7 @@ int tls_connect (transport_endpoint_cfg_t * tep) { vnet_connect_args_t _cargs = { {}, }, *cargs = &_cargs; + transport_endpt_crypto_cfg_t *ccfg; crypto_engine_type_t engine_type; session_endpoint_cfg_t *sep; tls_main_t *tm = &tls_main; @@ -672,9 +680,14 @@ tls_connect (transport_endpoint_cfg_t * tep) int rv; sep = (session_endpoint_cfg_t *) tep; + if (!sep->ext_cfg) + return -1; + app_wrk = app_worker_get (sep->app_wrk_index); app = application_get (app_wrk->app_index); - engine_type = tls_get_engine_type (app->tls_engine); + + ccfg = &sep->ext_cfg->crypto; + engine_type = tls_get_engine_type (ccfg->crypto_engine, app->tls_engine); if (engine_type == CRYPTO_ENGINE_NONE) { clib_warning ("No tls engine_type available"); @@ -686,11 +699,11 @@ tls_connect (transport_endpoint_cfg_t * tep) ctx->parent_app_wrk_index = sep->app_wrk_index; ctx->parent_app_api_context = sep->opaque; ctx->tcp_is_ip4 = sep->is_ip4; - ctx->ckpair_index = sep->ckpair_index; ctx->tls_type = sep->transport_proto; - if (sep->hostname) + ctx->ckpair_index = ccfg->ckpair_index; + if (ccfg->hostname[0]) { - ctx->srv_hostname = format (0, "%v", sep->hostname); + ctx->srv_hostname = format (0, "%s", ccfg->hostname); vec_terminate_c_string (ctx->srv_hostname); } tls_ctx_half_open_reader_unlock (); @@ -725,6 +738,7 @@ u32 tls_start_listen (u32 app_listener_index, transport_endpoint_t * tep) { vnet_listen_args_t _bargs, *args = &_bargs; + transport_endpt_crypto_cfg_t *ccfg; app_worker_t *app_wrk; tls_main_t *tm = &tls_main; session_handle_t tls_al_handle; @@ -738,9 +752,14 @@ tls_start_listen (u32 app_listener_index, transport_endpoint_t * tep) u32 lctx_index; sep = (session_endpoint_cfg_t *) tep; + if (!sep->ext_cfg) + return -1; + app_wrk = app_worker_get (sep->app_wrk_index); app = application_get (app_wrk->app_index); - engine_type = tls_get_engine_type (app->tls_engine); + + ccfg = &sep->ext_cfg->crypto; + engine_type = tls_get_engine_type (ccfg->crypto_engine, app->tls_engine); if (engine_type == CRYPTO_ENGINE_NONE) { clib_warning ("No tls engine_type available"); @@ -774,8 +793,8 @@ tls_start_listen (u32 app_listener_index, transport_endpoint_t * tep) lctx->app_session_handle = listen_session_get_handle (app_listener); lctx->tcp_is_ip4 = sep->is_ip4; lctx->tls_ctx_engine = engine_type; - lctx->ckpair_index = sep->ckpair_index; lctx->tls_type = sep->transport_proto; + lctx->ckpair_index = ccfg->ckpair_index; if (tls_vfts[engine_type].ctx_start_listen (lctx)) { @@ -1076,6 +1095,7 @@ int dtls_connect (transport_endpoint_cfg_t *tep) { vnet_connect_args_t _cargs = { {}, }, *cargs = &_cargs; + transport_endpt_crypto_cfg_t *ccfg; crypto_engine_type_t engine_type; session_endpoint_cfg_t *sep; tls_main_t *tm = &tls_main; @@ -1086,9 +1106,14 @@ dtls_connect (transport_endpoint_cfg_t *tep) int rv; sep = (session_endpoint_cfg_t *) tep; + if (!sep->ext_cfg) + return -1; + app_wrk = app_worker_get (sep->app_wrk_index); app = application_get (app_wrk->app_index); - engine_type = tls_get_engine_type (app->tls_engine); + + ccfg = &sep->ext_cfg->crypto; + engine_type = tls_get_engine_type (ccfg->crypto_engine, app->tls_engine); if (engine_type == CRYPTO_ENGINE_NONE) { clib_warning ("No tls engine_type available"); @@ -1100,12 +1125,12 @@ dtls_connect (transport_endpoint_cfg_t *tep) ctx->parent_app_wrk_index = sep->app_wrk_index; ctx->parent_app_api_context = sep->opaque; ctx->tcp_is_ip4 = sep->is_ip4; - ctx->ckpair_index = sep->ckpair_index; + ctx->ckpair_index = ccfg->ckpair_index; ctx->tls_type = sep->transport_proto; ctx->tls_ctx_handle = ctx_handle; - if (sep->hostname) + if (ccfg->hostname[0]) { - ctx->srv_hostname = format (0, "%v", sep->hostname); + ctx->srv_hostname = format (0, "%s", ccfg->hostname); vec_terminate_c_string (ctx->srv_hostname); } -- 2.16.6