summaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
authorqinyang <qiny@yusur.tech>2023-06-27 01:11:53 -0700
committerFlorin Coras <florin.coras@gmail.com>2023-07-21 16:27:14 +0000
commitaf9b7156c8fd16c671ce9332613faaf864b075b3 (patch)
tree201f45dacba23771db635c563b34315b6594d4af /src/vnet
parentae916b39049669bbada12dbcfecbb4e3f9c09c69 (diff)
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 <qiny@yusur.tech>
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/session/application.c6
-rw-r--r--src/vnet/session/application.h1
-rw-r--r--src/vnet/session/application_interface.h23
-rw-r--r--src/vnet/session/session.c22
-rw-r--r--src/vnet/session/session.h11
-rw-r--r--src/vnet/session/session_api.c7
6 files changed, 60 insertions, 10 deletions
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 <vnet/plugin/plugin.h>
#include <vnet/session/session.h>
#include <vnet/session/application.h>
#include <vnet/dpo/load_balance.h>
@@ -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;