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/vcl/ldp.c | 19 +++++++++++++++++++ src/vcl/vcl_bapi.c | 3 ++- src/vcl/vcl_cfg.c | 5 +++++ src/vcl/vcl_private.h | 4 ++++ src/vcl/vcl_sapi.c | 3 ++- src/vcl/vppcom.c | 32 ++++++++++++++++++++++++++++++++ src/vcl/vppcom.h | 1 + 7 files changed, 65 insertions(+), 2 deletions(-) (limited to 'src/vcl') diff --git a/src/vcl/ldp.c b/src/vcl/ldp.c index 2256a2b9061..a8062b4ca8d 100644 --- a/src/vcl/ldp.c +++ b/src/vcl/ldp.c @@ -67,6 +67,10 @@ #define UDP_SEGMENT 103 #endif +#ifndef SO_ORIGINAL_DST +/* from */ +#define SO_ORIGINAL_DST 80 +#endif typedef struct ldp_worker_ctx_ { u8 *io_buffer; @@ -2043,6 +2047,21 @@ getsockopt (int fd, int level, int optname, break; } break; + case SOL_IP: + switch (optname) + { + case SO_ORIGINAL_DST: + rv = + vls_attr (vlsh, VPPCOM_ATTR_GET_ORIGINAL_DST, optval, optlen); + break; + default: + LDBG (0, + "ERROR: fd %d: getsockopt SOL_IP: vlsh %u " + "optname %d unsupported!", + fd, vlsh, optname); + break; + } + break; case SOL_IPV6: switch (optname) { diff --git a/src/vcl/vcl_bapi.c b/src/vcl/vcl_bapi.c index afe8824812f..6071f646da4 100644 --- a/src/vcl/vcl_bapi.c +++ b/src/vcl/vcl_bapi.c @@ -360,7 +360,8 @@ vcl_bapi_send_attach (void) (vcm->cfg.app_scope_global ? APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE : 0) | (app_is_proxy ? APP_OPTIONS_FLAGS_IS_PROXY : 0) | (vcm->cfg.use_mq_eventfd ? APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD : 0) | - (vcm->cfg.huge_page ? APP_OPTIONS_FLAGS_USE_HUGE_PAGE : 0); + (vcm->cfg.huge_page ? APP_OPTIONS_FLAGS_USE_HUGE_PAGE : 0) | + (vcm->cfg.app_original_dst ? APP_OPTIONS_FLAGS_GET_ORIGINAL_DST : 0); bmp->options[APP_OPTIONS_PROXY_TRANSPORT] = (u64) ((vcm->cfg.app_proxy_transport_tcp ? 1 << TRANSPORT_PROTO_TCP : 0) | (vcm->cfg.app_proxy_transport_udp ? 1 << TRANSPORT_PROTO_UDP : 0)); diff --git a/src/vcl/vcl_cfg.c b/src/vcl/vcl_cfg.c index be142eaeb58..edea60dc60a 100644 --- a/src/vcl/vcl_cfg.c +++ b/src/vcl/vcl_cfg.c @@ -464,6 +464,11 @@ vppcom_cfg_read_file (char *conf_fname) VCFG_DBG (0, "VCL<%d>: configured with multithread workers", getpid ()); } + else if (unformat (line_input, "app_original_dst")) + { + vcl_cfg->app_original_dst = 1; + VCFG_DBG (0, "VCL<%d>: support original destination", getpid ()); + } else if (unformat (line_input, "}")) { vc_cfg_input = 0; diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h index 39a0f05034f..8345e34e0c1 100644 --- a/src/vcl/vcl_private.h +++ b/src/vcl/vcl_private.h @@ -180,6 +180,9 @@ typedef struct vcl_session_ #if VCL_ELOG elog_track_t elog_track; #endif + + u16 original_dst_port; /**< original dst port (network order) */ + u32 original_dst_ip4; /**< original dst ip4 (network order) */ } vcl_session_t; typedef struct vppcom_cfg_t_ @@ -208,6 +211,7 @@ typedef struct vppcom_cfg_t_ u32 tls_engine; u8 mt_wrk_supported; u8 huge_page; + u8 app_original_dst; } vppcom_cfg_t; void vppcom_cfg (vppcom_cfg_t * vcl_cfg); diff --git a/src/vcl/vcl_sapi.c b/src/vcl/vcl_sapi.c index 3a97fa25c0a..e3e2b6ac377 100644 --- a/src/vcl/vcl_sapi.c +++ b/src/vcl/vcl_sapi.c @@ -130,7 +130,8 @@ vcl_api_send_attach (clib_socket_t * cs) (vcm->cfg.app_scope_global ? APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE : 0) | (app_is_proxy ? APP_OPTIONS_FLAGS_IS_PROXY : 0) | (vcm->cfg.use_mq_eventfd ? APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD : 0) | - (vcm->cfg.huge_page ? APP_OPTIONS_FLAGS_USE_HUGE_PAGE : 0); + (vcm->cfg.huge_page ? APP_OPTIONS_FLAGS_USE_HUGE_PAGE : 0) | + (vcm->cfg.app_original_dst ? APP_OPTIONS_FLAGS_GET_ORIGINAL_DST : 0); mp->options[APP_OPTIONS_PROXY_TRANSPORT] = (u64) ((vcm->cfg.app_proxy_transport_tcp ? 1 << TRANSPORT_PROTO_TCP : 0) | (vcm->cfg.app_proxy_transport_udp ? 1 << TRANSPORT_PROTO_UDP : 0)); diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index d9cc885bb0e..06a345d5792 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -351,6 +351,11 @@ vcl_session_accepted_handler (vcl_worker_t * wrk, session_accepted_msg_t * mp, session->vpp_handle = mp->handle; session->session_state = VCL_STATE_READY; + if (mp->rmt.is_ip4) + { + session->original_dst_ip4 = mp->original_dst_ip4; + session->original_dst_port = mp->original_dst_port; + } session->transport.rmt_port = mp->rmt.port; session->transport.is_ip4 = mp->rmt.is_ip4; clib_memcpy_fast (&session->transport.rmt_ip, &mp->rmt.ip, @@ -3611,6 +3616,33 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op, rv = VPPCOM_EINVAL; break; + case VPPCOM_ATTR_GET_ORIGINAL_DST: + if (!session->transport.is_ip4) + { + /* now original dst only support ipv4*/ + rv = VPPCOM_EAFNOSUPPORT; + break; + } + if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*ep)) && + ep->ip)) + { + ep->is_ip4 = session->transport.is_ip4; + ep->port = session->original_dst_port; + clib_memcpy_fast (ep->ip, &session->original_dst_ip4, + sizeof (ip4_address_t)); + *buflen = sizeof (*ep); + VDBG (1, + "VPPCOM_ATTR_GET_ORIGINAL_DST: sh %u, is_ip4 = %u, addr = %U" + " port %d", + session_handle, ep->is_ip4, vcl_format_ip4_address, + (ip4_address_t *) (&session->original_dst_ip4), + ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6, + clib_net_to_host_u16 (ep->port)); + } + else + rv = VPPCOM_EINVAL; + break; + case VPPCOM_ATTR_SET_LCL_ADDR: if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*ep)) && ep->ip)) diff --git a/src/vcl/vppcom.h b/src/vcl/vppcom.h index 71a49ab3480..7826076a338 100644 --- a/src/vcl/vppcom.h +++ b/src/vcl/vppcom.h @@ -176,6 +176,7 @@ typedef enum VPPCOM_ATTR_SET_DSCP, VPPCOM_ATTR_SET_IP_PKTINFO, VPPCOM_ATTR_GET_IP_PKTINFO, + VPPCOM_ATTR_GET_ORIGINAL_DST, } vppcom_attr_op_t; typedef struct _vcl_poll -- cgit 1.2.3-korg