aboutsummaryrefslogtreecommitdiffstats
path: root/src/vcl
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/vcl
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/vcl')
-rw-r--r--src/vcl/ldp.c19
-rw-r--r--src/vcl/vcl_bapi.c3
-rw-r--r--src/vcl/vcl_cfg.c5
-rw-r--r--src/vcl/vcl_private.h4
-rw-r--r--src/vcl/vcl_sapi.c3
-rw-r--r--src/vcl/vppcom.c32
-rw-r--r--src/vcl/vppcom.h1
7 files changed, 65 insertions, 2 deletions
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 <linux/netfilter_ipv4.h> */
+#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