aboutsummaryrefslogtreecommitdiffstats
path: root/src/vcl/vppcom.c
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/vppcom.c
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/vppcom.c')
-rw-r--r--src/vcl/vppcom.c32
1 files changed, 32 insertions, 0 deletions
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))