From 4ac258497303c1cbca539e04ef5f732eed24a5c4 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Mon, 19 Apr 2021 17:34:54 -0700 Subject: [PATCH] vcl session: extended connect/listen configuration Type: feature Signed-off-by: Florin Coras Change-Id: Ic8d9386fef37ffd3446aaeb93a96ee6d60633831 --- src/vcl/vcl_private.c | 26 +++++++++++++++++++++++ src/vcl/vcl_private.h | 5 +++++ src/vcl/vppcom.c | 27 ++++++++++++++++++++++++ src/vnet/session/application_interface.h | 15 +++++++++++-- src/vnet/session/session_node.c | 36 +++++++++++++++++++++++++++++++- src/vnet/session/session_types.h | 25 +++++++++------------- src/vnet/session/transport_types.h | 7 +++++++ 7 files changed, 123 insertions(+), 18 deletions(-) diff --git a/src/vcl/vcl_private.c b/src/vcl/vcl_private.c index ba54c91f5cd..721416b045a 100644 --- a/src/vcl/vcl_private.c +++ b/src/vcl/vcl_private.c @@ -519,6 +519,32 @@ vcl_segment_discover_mqs (uword segment_handle, int *fds, u32 n_fds) return 0; } +svm_fifo_chunk_t * +vcl_segment_alloc_chunk (uword segment_handle, u32 slice_index, u32 size, + uword *offset) +{ + svm_fifo_chunk_t *c; + fifo_segment_t *fs; + u32 fs_index; + + fs_index = vcl_segment_table_lookup (segment_handle); + if (fs_index == VCL_INVALID_SEGMENT_INDEX) + { + VDBG (0, "ERROR: mq segment %lx for is not attached!", segment_handle); + return 0; + } + + clib_rwlock_reader_lock (&vcm->segment_table_lock); + + fs = fifo_segment_get_segment (&vcm->segment_main, fs_index); + c = fifo_segment_alloc_chunk_w_slice (fs, slice_index, size); + *offset = fifo_segment_chunk_offset (fs, c); + + clib_rwlock_reader_unlock (&vcm->segment_table_lock); + + return c; +} + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h index 34e05f20f88..1da334a1da9 100644 --- a/src/vcl/vcl_private.h +++ b/src/vcl/vcl_private.h @@ -166,6 +166,8 @@ typedef struct vcl_session_ u32 sndbuf_size; // VPP-TBD: Hack until support setsockopt(SO_SNDBUF) u32 rcvbuf_size; // VPP-TBD: Hack until support setsockopt(SO_RCVBUF) + transport_endpt_ext_cfg_t *ext_config; + #if VCL_ELOG elog_track_t elog_track; #endif @@ -709,6 +711,9 @@ int vcl_segment_attach_session (uword segment_handle, uword rxf_offset, int vcl_segment_attach_mq (uword segment_handle, uword mq_offset, u32 mq_index, svm_msg_q_t **mq); int vcl_segment_discover_mqs (uword segment_handle, int *fds, u32 n_fds); +svm_fifo_chunk_t *vcl_segment_alloc_chunk (uword segment_handle, + u32 slice_index, u32 size, + uword *offset); /* * VCL Binary API diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index ce678893167..1ece9db9940 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -163,6 +163,18 @@ format_ip46_address (u8 * s, va_list * args) * VPPCOM Utility Functions */ +static void +vcl_msg_add_ext_config (vcl_session_t *s, uword *offset) +{ + svm_fifo_chunk_t *c; + + c = vcl_segment_alloc_chunk (vcl_vpp_worker_segment_handle (0), + 0 /* one slice only */, s->ext_config->len, + offset); + if (c) + clib_memcpy_fast (c->data, s->ext_config, s->ext_config->len); +} + static void vcl_send_session_listen (vcl_worker_t * wrk, vcl_session_t * s) { @@ -185,7 +197,14 @@ vcl_send_session_listen (vcl_worker_t * wrk, vcl_session_t * s) mp->vrf = s->vrf; if (s->flags & VCL_SESSION_F_CONNECTED) mp->flags = TRANSPORT_CFG_F_CONNECTED; + if (s->ext_config) + vcl_msg_add_ext_config (s, &mp->ext_config); app_send_ctrl_evt_to_vpp (mq, app_evt); + if (s->ext_config) + { + clib_mem_free (s->ext_config); + s->ext_config = 0; + } } static void @@ -213,7 +232,15 @@ vcl_send_session_connect (vcl_worker_t * wrk, vcl_session_t * s) mp->vrf = s->vrf; if (s->flags & VCL_SESSION_F_CONNECTED) mp->flags |= TRANSPORT_CFG_F_CONNECTED; + if (s->ext_config) + vcl_msg_add_ext_config (s, &mp->ext_config); app_send_ctrl_evt_to_vpp (mq, app_evt); + + if (s->ext_config) + { + clib_mem_free (s->ext_config); + s->ext_config = 0; + } } void diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h index 3f333af86b9..be6c74c6529 100644 --- a/src/vnet/session/application_interface.h +++ b/src/vnet/session/application_interface.h @@ -317,6 +317,7 @@ typedef struct session_listen_msg_ u32 ckpair_index; u8 crypto_engine; u8 flags; + uword ext_config; } __clib_packed session_listen_msg_t; STATIC_ASSERT (sizeof (session_listen_msg_t) <= SESSION_CTRL_MSG_MAX_SIZE, @@ -394,12 +395,22 @@ typedef struct session_connect_msg_ u8 is_ip4; ip46_address_t ip; ip46_address_t lcl_ip; - u8 hostname_len; - u8 hostname[16]; u64 parent_handle; u32 ckpair_index; u8 crypto_engine; u8 flags; + union + { + struct + { + u8 hostname[16]; + u8 hostname_len; + } __clib_packed; + struct + { + uword ext_config; + } __clib_packed; + }; } __clib_packed session_connect_msg_t; STATIC_ASSERT (sizeof (session_connect_msg_t) <= SESSION_CTRL_MSG_MAX_SIZE, diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c index 22ab3e8c064..a4db02362d3 100644 --- a/src/vnet/session/session_node.c +++ b/src/vnet/session/session_node.c @@ -33,6 +33,29 @@ return; \ } +static transport_endpt_ext_cfg_t * +session_mq_get_ext_config (application_t *app, uword offset) +{ + svm_fifo_chunk_t *c; + fifo_segment_t *fs; + + fs = application_get_rx_mqs_segment (app); + c = fs_chunk_ptr (fs->h, offset); + return (transport_endpt_ext_cfg_t *) c->data; +} + +static void +session_mq_free_ext_config (application_t *app, uword offset) +{ + u32 ctrl_thread = vlib_num_workers () ? 1 : 0; + svm_fifo_chunk_t *c; + fifo_segment_t *fs; + + fs = application_get_rx_mqs_segment (app); + c = fs_chunk_ptr (fs->h, offset); + fifo_segment_collect_chunk (fs, ctrl_thread, c); +} + static void session_mq_listen_handler (void *data) { @@ -61,12 +84,17 @@ session_mq_listen_handler (void *data) a->wrk_map_index = mp->wrk_index; a->sep_ext.transport_flags = mp->flags; + if (mp->ext_config) + a->sep_ext.ext_cfg = session_mq_get_ext_config (app, mp->ext_config); + if ((rv = vnet_listen (a))) clib_warning ("listen returned: %U", format_session_error, rv); app_wrk = application_get_worker (app, mp->wrk_index); mq_send_session_bound_cb (app_wrk->wrk_index, mp->context, a->handle, rv); - return; + + if (mp->ext_config) + session_mq_free_ext_config (app, mp->ext_config); } static void @@ -135,6 +163,9 @@ session_mq_connect_handler (void *data) a->app_index = app->app_index; a->wrk_map_index = mp->wrk_index; + if (mp->ext_config) + a->sep_ext.ext_cfg = session_mq_get_ext_config (app, mp->ext_config); + if ((rv = vnet_connect (a))) { clib_warning ("connect returned: %U", format_session_error, rv); @@ -142,6 +173,9 @@ session_mq_connect_handler (void *data) mq_send_session_connected_cb (app_wrk->wrk_index, mp->context, 0, rv); } + if (mp->ext_config) + session_mq_free_ext_config (app, mp->ext_config); + vec_free (a->sep_ext.hostname); } diff --git a/src/vnet/session/session_types.h b/src/vnet/session/session_types.h index 3a026a1a869..148f100f512 100644 --- a/src/vnet/session/session_types.h +++ b/src/vnet/session/session_types.h @@ -49,6 +49,7 @@ typedef struct _session_endpoint_cfg u32 ckpair_index; u8 crypto_engine; u8 flags; + transport_endpt_ext_cfg_t *ext_cfg; } session_endpoint_cfg_t; #define SESSION_IP46_ZERO \ @@ -76,21 +77,15 @@ typedef struct _session_endpoint_cfg .peer = TRANSPORT_ENDPOINT_NULL, \ .transport_proto = 0, \ } -#define SESSION_ENDPOINT_CFG_NULL \ -{ \ - .sw_if_index = ENDPOINT_INVALID_INDEX, \ - .ip = SESSION_IP46_ZERO, \ - .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 \ -} +#define SESSION_ENDPOINT_CFG_NULL \ + { \ + .sw_if_index = ENDPOINT_INVALID_INDEX, .ip = SESSION_IP46_ZERO, \ + .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, \ + } #define session_endpoint_to_transport(_sep) ((transport_endpoint_t *)_sep) #define session_endpoint_to_transport_cfg(_sep) \ diff --git a/src/vnet/session/transport_types.h b/src/vnet/session/transport_types.h index 5f14701f110..0041adb2c64 100644 --- a/src/vnet/session/transport_types.h +++ b/src/vnet/session/transport_types.h @@ -259,6 +259,13 @@ typedef struct transport_endpt_attr_ }; } transport_endpt_attr_t; +typedef struct transport_endpt_ext_cfg_ +{ + u16 type; + u16 len; + u8 data[0]; +} transport_endpt_ext_cfg_t; + typedef clib_bihash_24_8_t transport_endpoint_table_t; #define ENDPOINT_INVALID_INDEX ((u32)~0) -- 2.16.6