From af9b7156c8fd16c671ce9332613faaf864b075b3 Mon Sep 17 00:00:00 2001 From: qinyang Date: Tue, 27 Jun 2023 01:11:53 -0700 Subject: vcl: ldp support SO_ORIGINAL_DST Type: improvement Support SO_ORIGINAL_DST socket option to get original dst_ip4 and dst_port if nat44 rule enabled. Change-Id: If00e00d03e48f3b78a23a68f1b078954d79dd0f7 Signed-off-by: qinyang --- src/vnet/session/application.c | 6 ++++++ src/vnet/session/application.h | 1 + src/vnet/session/application_interface.h | 23 +++++++++++++---------- src/vnet/session/session.c | 22 ++++++++++++++++++++++ src/vnet/session/session.h | 11 +++++++++++ src/vnet/session/session_api.c | 7 +++++++ 6 files changed, 60 insertions(+), 10 deletions(-) (limited to 'src/vnet') diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c index cfa97190bf9..59989214231 100644 --- a/src/vnet/session/application.c +++ b/src/vnet/session/application.c @@ -1529,6 +1529,12 @@ application_has_global_scope (application_t * app) return app->flags & APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE; } +int +application_original_dst_is_enabled (application_t *app) +{ + return app->flags & APP_OPTIONS_FLAGS_GET_ORIGINAL_DST; +} + static clib_error_t * application_start_stop_proxy_fib_proto (application_t * app, u8 fib_proto, u8 transport_proto, u8 is_start) diff --git a/src/vnet/session/application.h b/src/vnet/session/application.h index 09737a6752d..e100fe89e63 100644 --- a/src/vnet/session/application.h +++ b/src/vnet/session/application.h @@ -300,6 +300,7 @@ u8 application_has_global_scope (application_t * app); void application_setup_proxy (application_t * app); void application_remove_proxy (application_t * app); void application_namespace_cleanup (app_namespace_t *app_ns); +int application_original_dst_is_enabled (application_t *app); segment_manager_props_t *application_get_segment_manager_properties (u32 app_index); diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h index 138953b4ed4..510068b7769 100644 --- a/src/vnet/session/application_interface.h +++ b/src/vnet/session/application_interface.h @@ -233,7 +233,8 @@ typedef enum _ (USE_LOCAL_SCOPE, "App can use local session scope") \ _ (EVT_MQ_USE_EVENTFD, "Use eventfds for signaling") \ _ (MEMFD_FOR_BUILTIN, "Use memfd for builtin app segs") \ - _ (USE_HUGE_PAGE, "Use huge page for FIFO") + _ (USE_HUGE_PAGE, "Use huge page for FIFO") \ + _ (GET_ORIGINAL_DST, "Get original dst enabled") typedef enum _app_options { @@ -299,15 +300,15 @@ typedef struct app_session_transport_ u8 is_ip4; /**< set if uses ip4 networking */ } app_session_transport_t; -#define foreach_app_session_field \ - _(svm_fifo_t, *rx_fifo) /**< rx fifo */ \ - _(svm_fifo_t, *tx_fifo) /**< tx fifo */ \ - _(session_type_t, session_type) /**< session type */ \ - _(volatile u8, session_state) /**< session state */ \ - _(u32, session_index) /**< index in owning pool */ \ - _(app_session_transport_t, transport) /**< transport info */ \ - _(svm_msg_q_t, *vpp_evt_q) /**< vpp event queue */ \ - _(u8, is_dgram) /**< flag for dgram mode */ \ +#define foreach_app_session_field \ + _ (svm_fifo_t, *rx_fifo) /**< rx fifo */ \ + _ (svm_fifo_t, *tx_fifo) /**< tx fifo */ \ + _ (session_type_t, session_type) /**< session type */ \ + _ (volatile u8, session_state) /**< session state */ \ + _ (u32, session_index) /**< index in owning pool */ \ + _ (app_session_transport_t, transport) /**< transport info */ \ + _ (svm_msg_q_t, *vpp_evt_q) /**< vpp event queue */ \ + _ (u8, is_dgram) /**< flag for dgram mode */ typedef struct { @@ -386,6 +387,8 @@ typedef struct session_accepted_msg_ transport_endpoint_t lcl; transport_endpoint_t rmt; u8 flags; + u32 original_dst_ip4; + u16 original_dst_port; } __clib_packed session_accepted_msg_t; typedef struct session_accepted_reply_msg_ diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c index 5bb57761c90..228234ceefc 100644 --- a/src/vnet/session/session.c +++ b/src/vnet/session/session.c @@ -17,6 +17,7 @@ * @brief Session and session manager */ +#include #include #include #include @@ -1762,6 +1763,22 @@ session_segment_handle (session_t * s) f->segment_index); } +void +session_get_original_dst (transport_endpoint_t *i2o_src, + transport_endpoint_t *i2o_dst, + transport_proto_t transport_proto, u32 *original_dst, + u16 *original_dst_port) +{ + session_main_t *smm = vnet_get_session_main (); + ip_protocol_t proto = + (transport_proto == TRANSPORT_PROTO_TCP ? IPPROTO_TCP : IPPROTO_UDP); + if (!smm->original_dst_lookup || !i2o_dst->is_ip4) + return; + smm->original_dst_lookup (&i2o_src->ip.ip4, i2o_src->port, &i2o_dst->ip.ip4, + i2o_dst->port, proto, original_dst, + original_dst_port); +} + /* *INDENT-OFF* */ static session_fifo_rx_fn *session_tx_fns[TRANSPORT_TX_N_FNS] = { session_tx_fifo_peek_and_snd, @@ -2292,6 +2309,11 @@ session_config_fn (vlib_main_t * vm, unformat_input_t * input) smm->no_adaptive = 1; else if (unformat (input, "use-dma")) smm->dma_enabled = 1; + else if (unformat (input, "nat44-original-dst-enable")) + { + smm->original_dst_lookup = vlib_get_plugin_symbol ( + "nat_plugin.so", "nat44_original_dst_lookup"); + } /* * Deprecated but maintained for compatibility */ diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h index 10bae273d85..9c08f1a4d04 100644 --- a/src/vnet/session/session.h +++ b/src/vnet/session/session.h @@ -193,6 +193,10 @@ extern session_fifo_rx_fn session_tx_fifo_dequeue_internal; u8 session_node_lookup_fifo_event (svm_fifo_t * f, session_event_t * e); typedef void (*session_update_time_fn) (f64 time_now, u8 thread_index); +typedef void (*nat44_original_dst_lookup_fn) ( + ip4_address_t *i2o_src, u16 i2o_src_port, ip4_address_t *i2o_dst, + u16 i2o_dst_port, ip_protocol_t proto, u32 *original_dst, + u16 *original_dst_port); typedef struct session_main_ { @@ -281,6 +285,9 @@ typedef struct session_main_ u32 preallocated_sessions; u16 msg_id_base; + + /** Query nat44-ed session to get original dst ip4 & dst port. */ + nat44_original_dst_lookup_fn original_dst_lookup; } session_main_t; extern session_main_t session_main; @@ -812,6 +819,10 @@ void session_wrk_handle_evts_main_rpc (void *); session_t *session_alloc_for_connection (transport_connection_t * tc); session_t *session_alloc_for_half_open (transport_connection_t *tc); +void session_get_original_dst (transport_endpoint_t *i2o_src, + transport_endpoint_t *i2o_dst, + transport_proto_t transport_proto, + u32 *original_dst, u16 *original_dst_port); typedef void (pool_safe_realloc_rpc_fn) (void *rpc_args); diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c index 3e99938dd6b..3d70733ceb2 100644 --- a/src/vnet/session/session_api.c +++ b/src/vnet/session/session_api.c @@ -136,6 +136,13 @@ mq_send_session_accepted_cb (session_t * s) m.mq_index = s->thread_index; } + if (application_original_dst_is_enabled (app)) + { + session_get_original_dst (&m.lcl, &m.rmt, + session_get_transport_proto (s), + &m.original_dst_ip4, &m.original_dst_port); + } + app_wrk_send_ctrl_evt (app_wrk, SESSION_CTRL_EVT_ACCEPTED, &m, sizeof (m)); return 0; -- cgit 1.2.3-korg