From: Matus Fabian Date: Wed, 8 Oct 2025 10:00:02 +0000 (-0400) Subject: session: make alpn more generic for transports X-Git-Url: https://gerrit.fd.io/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F61%2F43861%2F2;p=vpp.git session: make alpn more generic for transports - move all type definitions from tls_types to transport types - move hash table for alpn proto reverse lookup to transport_main - add get_alpn_selected to transport_proto_vft_t - add transport_get_alpn_selected as common function for negotiated alpn proto retrieval Type: refactor Change-Id: I8bde0844a6263f6ba023837b405c5b66c4781955 Signed-off-by: Matus Fabian --- diff --git a/src/plugins/hs_apps/alpn_client.c b/src/plugins/hs_apps/alpn_client.c index 8f744e17471..6195e9487e3 100644 --- a/src/plugins/hs_apps/alpn_client.c +++ b/src/plugins/hs_apps/alpn_client.c @@ -5,7 +5,6 @@ #include #include #include -#include typedef struct { @@ -63,7 +62,8 @@ ac_ts_connected_callback (u32 app_index, u32 api_context, session_t *s, return -1; } - cm->alpn_proto_selected = tls_get_alpn_selected (s->connection_index); + cm->alpn_proto_selected = transport_get_alpn_selected ( + session_get_transport_proto (s), s->connection_index, s->thread_index); a->handle = session_handle (s); a->app_index = cm->app_index; diff --git a/src/plugins/hs_apps/alpn_server.c b/src/plugins/hs_apps/alpn_server.c index ba0cc144bca..5ac82da7452 100644 --- a/src/plugins/hs_apps/alpn_server.c +++ b/src/plugins/hs_apps/alpn_server.c @@ -4,7 +4,6 @@ #include #include -#include typedef struct { @@ -40,7 +39,8 @@ as_ts_accept_callback (session_t *ts) ts->session_state = SESSION_STATE_READY; - alpn_proto = tls_get_alpn_selected (ts->connection_index); + alpn_proto = transport_get_alpn_selected ( + session_get_transport_proto (ts), ts->connection_index, ts->thread_index); clib_warning ("ALPN selected: %U", format_tls_alpn_proto, alpn_proto); return 0; diff --git a/src/plugins/hs_apps/http_cli.c b/src/plugins/hs_apps/http_cli.c index fdc549f21e0..127fffbff43 100644 --- a/src/plugins/hs_apps/http_cli.c +++ b/src/plugins/hs_apps/http_cli.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/src/plugins/hs_apps/http_client.c b/src/plugins/hs_apps/http_client.c index 8a047fc9c36..36ee5fb0bec 100644 --- a/src/plugins/hs_apps/http_client.c +++ b/src/plugins/hs_apps/http_client.c @@ -10,7 +10,6 @@ #include #include #include -#include #define foreach_hc_s_flag \ _ (1, IS_CLOSED) \ diff --git a/src/plugins/hs_apps/http_connect_proxy_client.c b/src/plugins/hs_apps/http_connect_proxy_client.c index c06324313b4..fa850ec864a 100644 --- a/src/plugins/hs_apps/http_connect_proxy_client.c +++ b/src/plugins/hs_apps/http_connect_proxy_client.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include diff --git a/src/plugins/hs_apps/proxy.c b/src/plugins/hs_apps/proxy.c index 7d4e2f08997..5bbac450940 100644 --- a/src/plugins/hs_apps/proxy.c +++ b/src/plugins/hs_apps/proxy.c @@ -20,7 +20,6 @@ #include #include #include -#include proxy_main_t proxy_main; diff --git a/src/plugins/http/http.c b/src/plugins/http/http.c index 71baccf101b..0ef19a51358 100644 --- a/src/plugins/http/http.c +++ b/src/plugins/http/http.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -457,7 +456,8 @@ http_ts_accept_callback (session_t *ts) tp = session_get_transport_proto (ts); if (tp == TRANSPORT_PROTO_TLS) { - alpn_proto = tls_get_alpn_selected (ts->connection_index); + alpn_proto = transport_get_alpn_selected (tp, ts->connection_index, + ts->thread_index); HTTP_DBG (1, "ALPN selected: %U", format_tls_alpn_proto, alpn_proto); switch (alpn_proto) { @@ -544,7 +544,8 @@ http_ts_connected_callback (u32 http_app_index, u32 ho_hc_index, session_t *ts, /* TLS set by ALPN result, TCP: prior knowledge (set in ho) */ if (tp == TRANSPORT_PROTO_TLS) { - alpn_proto = tls_get_alpn_selected (ts->connection_index); + alpn_proto = transport_get_alpn_selected (tp, ts->connection_index, + ts->thread_index); HTTP_DBG (1, "ALPN selected: %U", format_tls_alpn_proto, alpn_proto); switch (alpn_proto) { diff --git a/src/plugins/http_static/static_server.c b/src/plugins/http_static/static_server.c index 25606ec96a8..47c6cc0c830 100644 --- a/src/plugins/http_static/static_server.c +++ b/src/plugins/http_static/static_server.c @@ -15,7 +15,6 @@ #include #include -#include #include #include diff --git a/src/vnet/CMakeLists.txt b/src/vnet/CMakeLists.txt index 891ed71d4db..8d62922bf48 100644 --- a/src/vnet/CMakeLists.txt +++ b/src/vnet/CMakeLists.txt @@ -1028,7 +1028,6 @@ list(APPEND VNET_HEADERS tls/tls_inlines.h tls/tls_record.h tls/tls_test.h - tls/tls_types.h ) diff --git a/src/vnet/session/transport.c b/src/vnet/session/transport.c index fa3106a2c57..e85eec48ac1 100644 --- a/src/vnet/session/transport.c +++ b/src/vnet/session/transport.c @@ -40,6 +40,7 @@ typedef struct transport_main_ u16 port_allocator_max_src_port; u8 lcl_endpts_cleanup_pending; clib_spinlock_t local_endpoints_lock; + uword *alpn_proto_by_str; } transport_main_t; static transport_main_t tp_main; @@ -470,6 +471,16 @@ transport_connection_attribute (transport_proto_t tp, u32 conn_index, return tp_vfts[tp].attribute (conn_index, thread_index, is_get, attr); } +tls_alpn_proto_t +transport_get_alpn_selected (transport_proto_t tp, u32 conn_index, + clib_thread_index_t thread_index) +{ + if (!tp_vfts[tp].get_alpn_selected) + return TLS_ALPN_PROTO_NONE; + + return tp_vfts[tp].get_alpn_selected (conn_index, thread_index); +} + #define PORT_MASK ((1 << 16)- 1) void @@ -989,6 +1000,53 @@ transport_connection_reschedule (transport_connection_t * tc) } } +tls_alpn_proto_t +tls_alpn_proto_by_str (tls_alpn_proto_id_t *alpn_id) +{ + transport_main_t *tm = &tp_main; + uword *p; + + p = hash_get_mem (tm->alpn_proto_by_str, alpn_id); + if (p) + return p[0]; + + return TLS_ALPN_PROTO_NONE; +} + +u8 * +format_tls_alpn_proto (u8 *s, va_list *args) +{ + tls_alpn_proto_t alpn_proto = va_arg (*args, int); + u8 *t = 0; + + switch (alpn_proto) + { +#define _(sym, str) \ + case TLS_ALPN_PROTO_##sym: \ + t = (u8 *) str; \ + break; + foreach_tls_alpn_protos +#undef _ + default : return format (s, "BUG: unknown"); + } + return format (s, "%s", t); +} + +static uword +tls_alpn_proto_hash_key_sum (hash_t *h, uword key) +{ + tls_alpn_proto_id_t *id = uword_to_pointer (key, tls_alpn_proto_id_t *); + return hash_memory (id->base, id->len, 0); +} + +static uword +tls_alpn_proto_hash_key_equal (hash_t *h, uword key1, uword key2) +{ + tls_alpn_proto_id_t *id1 = uword_to_pointer (key1, tls_alpn_proto_id_t *); + tls_alpn_proto_id_t *id2 = uword_to_pointer (key2, tls_alpn_proto_id_t *); + return id1 && id2 && tls_alpn_proto_id_eq (id1, id2); +} + void transport_fifos_init_ooo (transport_connection_t * tc) { @@ -1029,6 +1087,7 @@ transport_init (void) vlib_thread_main_t *vtm = vlib_get_thread_main (); session_main_t *smm = vnet_get_session_main (); transport_main_t *tm = &tp_main; + const tls_alpn_proto_id_t *alpn_proto; u32 num_threads; if (smm->local_endpoints_table_buckets == 0) @@ -1052,6 +1111,16 @@ transport_init (void) /* Main not polled if there are workers */ smm->transport_cl_thread = 1; } + + tm->alpn_proto_by_str = hash_create2 ( + 0, sizeof (tls_alpn_proto_id_t), sizeof (uword), + tls_alpn_proto_hash_key_sum, tls_alpn_proto_hash_key_equal, 0, 0); + +#define _(sym, str) \ + alpn_proto = &tls_alpn_proto_ids[TLS_ALPN_PROTO_##sym]; \ + hash_set_mem (tm->alpn_proto_by_str, alpn_proto, TLS_ALPN_PROTO_##sym); + foreach_tls_alpn_protos +#undef _ } /* diff --git a/src/vnet/session/transport.h b/src/vnet/session/transport.h index 31ad36bdc67..10477b9da67 100644 --- a/src/vnet/session/transport.h +++ b/src/vnet/session/transport.h @@ -120,6 +120,8 @@ typedef struct _transport_proto_vft u8 is_lcl); int (*attribute) (u32 conn_index, clib_thread_index_t thread_index, u8 is_get, transport_endpt_attr_t *attr); + tls_alpn_proto_t (*get_alpn_selected) (u32 conn_index, + clib_thread_index_t thread_index); /* * Properties @@ -153,6 +155,9 @@ void transport_get_listener_endpoint (transport_proto_t tp, u32 conn_index, int transport_connection_attribute (transport_proto_t tp, u32 conn_index, u8 thread_index, u8 is_get, transport_endpt_attr_t *attr); +tls_alpn_proto_t +transport_get_alpn_selected (transport_proto_t tp, u32 conn_index, + clib_thread_index_t thread_index); static inline transport_connection_t * transport_get_connection (transport_proto_t tp, u32 conn_index, diff --git a/src/vnet/session/transport_types.h b/src/vnet/session/transport_types.h index 71e19758777..5c86fd6ea8b 100644 --- a/src/vnet/session/transport_types.h +++ b/src/vnet/session/transport_types.h @@ -350,6 +350,30 @@ typedef enum tls_alpn_proto_ #undef _ } __clib_packed tls_alpn_proto_t; +typedef struct tls_alpn_proto_id_ +{ + u8 len; + u8 *base; +} tls_alpn_proto_id_t; + +static const tls_alpn_proto_id_t tls_alpn_proto_ids[] = { +#define _(sym, str) { (u8) (sizeof (str) - 1), (u8 *) str }, + foreach_tls_alpn_protos +#undef _ +}; + +static_always_inline u8 +tls_alpn_proto_id_eq (tls_alpn_proto_id_t *actual, + tls_alpn_proto_id_t *expected) +{ + if (actual->len != expected->len) + return 0; + return memcmp (actual->base, expected->base, expected->len) == 0 ? 1 : 0; +} + +tls_alpn_proto_t tls_alpn_proto_by_str (tls_alpn_proto_id_t *alpn_id); +format_function_t format_tls_alpn_proto; + typedef struct transport_endpt_crypto_cfg_ { u32 ckpair_index; /**< index of ck pair in application crypto layer */ diff --git a/src/vnet/tls/tls.c b/src/vnet/tls/tls.c index 3cdc4c1974d..745c96c15b0 100644 --- a/src/vnet/tls/tls.c +++ b/src/vnet/tls/tls.c @@ -23,12 +23,6 @@ tls_engine_vft_t *tls_vfts; void tls_disconnect (u32 ctx_handle, clib_thread_index_t thread_index); -static const tls_alpn_proto_id_t tls_alpn_proto_ids[] = { -#define _(sym, str) { (u8) (sizeof (str) - 1), (u8 *) str }, - foreach_tls_alpn_protos -#undef _ -}; - void tls_disconnect_transport (tls_ctx_t * ctx) { @@ -111,45 +105,12 @@ tls_add_app_q_evt (app_worker_t *app_wrk, session_t *app_session) } tls_alpn_proto_t -tls_alpn_proto_by_str (tls_alpn_proto_id_t *alpn_id) -{ - tls_main_t *tm = &tls_main; - uword *p; - - p = hash_get_mem (tm->alpn_proto_by_str, alpn_id); - if (p) - return p[0]; - - return TLS_ALPN_PROTO_NONE; -} - -tls_alpn_proto_t -tls_get_alpn_selected (u32 ctx_handle) +tls_get_alpn_selected (u32 ctx_handle, clib_thread_index_t thread_index) { - tls_ctx_t *ctx; - ctx = tls_ctx_get (ctx_handle); + tls_ctx_t *ctx = tls_ctx_get_w_thread (ctx_handle, thread_index); return ctx->alpn_selected; } -u8 * -format_tls_alpn_proto (u8 *s, va_list *args) -{ - tls_alpn_proto_t alpn_proto = va_arg (*args, int); - u8 *t = 0; - - switch (alpn_proto) - { -#define _(sym, str) \ - case TLS_ALPN_PROTO_##sym: \ - t = (u8 *) str; \ - break; - foreach_tls_alpn_protos -#undef _ - default : return format (s, "BUG: unknown"); - } - return format (s, "%s", t); -} - u32 tls_listener_ctx_alloc (void) { @@ -1190,6 +1151,7 @@ static const transport_proto_vft_t tls_proto = { .format_listener = format_tls_listener, .get_transport_endpoint = tls_transport_endpoint_get, .get_transport_listener_endpoint = tls_transport_listener_endpoint_get, + .get_alpn_selected = tls_get_alpn_selected, .transport_options = { .name = "tls", .short_name = "J", @@ -1319,6 +1281,7 @@ static const transport_proto_vft_t dtls_proto = { .format_listener = format_tls_listener, .get_transport_endpoint = tls_transport_endpoint_get, .get_transport_listener_endpoint = tls_transport_listener_endpoint_get, + .get_alpn_selected = tls_get_alpn_selected, .transport_options = { .name = "dtls", .short_name = "D", @@ -1334,28 +1297,12 @@ tls_register_engine (const tls_engine_vft_t * vft, crypto_engine_type_t type) tls_vfts[type] = *vft; } -static uword -tls_alpn_proto_hash_key_sum (hash_t *h, uword key) -{ - tls_alpn_proto_id_t *id = uword_to_pointer (key, tls_alpn_proto_id_t *); - return hash_memory (id->base, id->len, 0); -} - -static uword -tls_alpn_proto_hash_key_equal (hash_t *h, uword key1, uword key2) -{ - tls_alpn_proto_id_t *id1 = uword_to_pointer (key1, tls_alpn_proto_id_t *); - tls_alpn_proto_id_t *id2 = uword_to_pointer (key2, tls_alpn_proto_id_t *); - return id1 && id2 && tls_alpn_proto_id_eq (id1, id2); -} - static clib_error_t * tls_init (vlib_main_t * vm) { vlib_thread_main_t *vtm = vlib_get_thread_main (); tls_main_t *tm = &tls_main; u32 num_threads; - const tls_alpn_proto_id_t *alpn_proto; num_threads = 1 /* main thread */ + vtm->n_threads; @@ -1382,16 +1329,6 @@ tls_init (vlib_main_t * vm) transport_register_protocol (TRANSPORT_PROTO_DTLS, &dtls_proto, FIB_PROTOCOL_IP6, ~0); - tm->alpn_proto_by_str = hash_create2 ( - 0, sizeof (tls_alpn_proto_id_t), sizeof (uword), - tls_alpn_proto_hash_key_sum, tls_alpn_proto_hash_key_equal, 0, 0); - -#define _(sym, str) \ - alpn_proto = &tls_alpn_proto_ids[TLS_ALPN_PROTO_##sym]; \ - hash_set_mem (tm->alpn_proto_by_str, alpn_proto, TLS_ALPN_PROTO_##sym); - foreach_tls_alpn_protos -#undef _ - return 0; } diff --git a/src/vnet/tls/tls.h b/src/vnet/tls/tls.h index c575fc70ebd..4e7c6f96e46 100644 --- a/src/vnet/tls/tls.h +++ b/src/vnet/tls/tls.h @@ -16,7 +16,6 @@ #include #include #include -#include #include #ifndef SRC_VNET_TLS_TLS_H_ @@ -140,7 +139,6 @@ typedef struct tls_main_ u8 **rx_bufs; u8 **tx_bufs; - uword *alpn_proto_by_str; /* * Config */ diff --git a/src/vnet/tls/tls_types.h b/src/vnet/tls/tls_types.h deleted file mode 100644 index bf201b1af55..00000000000 --- a/src/vnet/tls/tls_types.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 - * Copyright(c) 2025 Cisco Systems, Inc. - */ - -#ifndef SRC_VNET_TLS_TLS_TYPES_H_ -#define SRC_VNET_TLS_TLS_TYPES_H_ - -#include - -typedef struct tls_alpn_proto_id_ -{ - u8 len; - u8 *base; -} tls_alpn_proto_id_t; - -static inline u8 -tls_alpn_proto_id_eq (tls_alpn_proto_id_t *actual, - tls_alpn_proto_id_t *expected) -{ - if (actual->len != expected->len) - return 0; - return memcmp (actual->base, expected->base, expected->len) == 0 ? 1 : 0; -} - -tls_alpn_proto_t tls_alpn_proto_by_str (tls_alpn_proto_id_t *alpn_id); - -tls_alpn_proto_t tls_get_alpn_selected (u32 ctx_handle); - -format_function_t format_tls_alpn_proto; - -#endif /* SRC_VNET_TLS_TLS_TYPES_H_ */