session vcl: add support for vcl transport attributes

Session layer can push transport attributes to vcl sessions which are
stored as vector for session lifetime.

Store original_dst_ip and port when available in vcl session attribute
vector.

Type: feature

Change-Id: Iab6c65ddcfed220fc919f564cd19083561812faf
Signed-off-by: Florin Coras <fcoras@cisco.com>
This commit is contained in:
Florin Coras
2024-10-03 00:34:03 -07:00
committed by Dave Wallace
parent 89969288d3
commit 28955ceb8b
5 changed files with 96 additions and 23 deletions

View File

@ -181,8 +181,7 @@ typedef struct vcl_session_
elog_track_t elog_track;
#endif
u16 original_dst_port; /**< original dst port (network order) */
u32 original_dst_ip4; /**< original dst ip4 (network order) */
transport_endpt_attr_t *tep_attrs; /**< vector of attributes */
} vcl_session_t;
typedef struct vppcom_cfg_t_
@ -409,6 +408,7 @@ vcl_session_free (vcl_worker_t * wrk, vcl_session_t * s)
vcl_session_detach_fifos (s);
if (s->ext_config)
clib_mem_free (s->ext_config);
vec_free (s->tep_attrs);
pool_put (wrk->sessions, s);
}
@ -664,6 +664,18 @@ vcl_session_clear_attr (vcl_session_t * s, u8 attr)
s->attributes &= ~(1 << attr);
}
static inline transport_endpt_attr_t *
vcl_session_tep_attr_get (vcl_session_t *s, transport_endpt_attr_type_t at)
{
transport_endpt_attr_t *tepa;
vec_foreach (tepa, s->tep_attrs)
{
if (tepa->type == at)
return tepa;
}
return 0;
}
static inline session_evt_type_t
vcl_session_dgram_tx_evt (vcl_session_t *s, session_evt_type_t et)
{

View File

@ -351,10 +351,16 @@ 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)
if (mp->rmt.is_ip4 && mp->original_dst_port)
{
session->original_dst_ip4 = mp->original_dst_ip4;
session->original_dst_port = mp->original_dst_port;
transport_endpt_attr_t *tep_attr;
vec_add2 (session->tep_attrs, tep_attr, 1);
/* Expecting to receive this on accepted connections
* and the external transport endpoint received is
* the local one, prior to something like nat */
tep_attr->type = TRANSPORT_ENDPT_ATTR_EXT_ENDPT;
tep_attr->ext_endpt.port = mp->original_dst_port;
tep_attr->ext_endpt.ip.ip4.as_u32 = mp->original_dst_ip4;
}
session->transport.rmt_port = mp->rmt.port;
session->transport.is_ip4 = mp->rmt.is_ip4;
@ -988,6 +994,24 @@ vcl_worker_rpc_handler (vcl_worker_t * wrk, void *data)
(vcm->wrk_rpc_fn) (((session_app_wrk_rpc_msg_t *) data)->data);
}
static void
vcl_session_transport_attr_handler (vcl_worker_t *wrk, void *data)
{
session_transport_attr_msg_t *mp = (session_transport_attr_msg_t *) data;
vcl_session_t *s;
s = vcl_session_get_w_vpp_handle (wrk, mp->handle);
if (!s)
{
VDBG (0, "session transport attr with wrong handle %llx", mp->handle);
return;
}
VDBG (0, "session %u [0x%llx]: transport attr %u", s->session_index,
s->vpp_handle, mp->attr.type);
vec_add1 (s->tep_attrs, mp->attr);
}
static void
vcl_session_transport_attr_reply_handler (vcl_worker_t *wrk, void *data)
{
@ -1129,6 +1153,9 @@ vcl_handle_mq_event (vcl_worker_t * wrk, session_event_t * e)
case SESSION_CTRL_EVT_APP_WRK_RPC:
vcl_worker_rpc_handler (wrk, e->data);
break;
case SESSION_CTRL_EVT_TRANSPORT_ATTR:
vcl_session_transport_attr_handler (wrk, e->data);
break;
case SESSION_CTRL_EVT_TRANSPORT_ATTR_REPLY:
vcl_session_transport_attr_reply_handler (wrk, e->data);
break;
@ -2607,6 +2634,9 @@ vcl_select_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
case SESSION_CTRL_EVT_APP_WRK_RPC:
vcl_worker_rpc_handler (wrk, e->data);
break;
case SESSION_CTRL_EVT_TRANSPORT_ATTR:
vcl_session_transport_attr_handler (wrk, e->data);
break;
default:
clib_warning ("unhandled: %u", e->event_type);
break;
@ -3382,6 +3412,9 @@ vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
case SESSION_CTRL_EVT_APP_WRK_RPC:
vcl_worker_rpc_handler (wrk, e->data);
break;
case SESSION_CTRL_EVT_TRANSPORT_ATTR:
vcl_session_transport_attr_handler (wrk, e->data);
break;
default:
VDBG (0, "unhandled: %u", e->event_type);
break;
@ -3672,7 +3705,7 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op,
vcl_worker_t *wrk = vcl_worker_get_current ();
u32 *flags = buffer;
vppcom_endpt_t *ep = buffer;
transport_endpt_attr_t tea;
transport_endpt_attr_t tea, *tepap;
vcl_session_t *session;
int rv = VPPCOM_OK;
@ -3795,24 +3828,49 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op,
rv = VPPCOM_EAFNOSUPPORT;
break;
}
if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*ep)) &&
ep->ip))
if (PREDICT_FALSE (!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));
rv = VPPCOM_EINVAL;
break;
}
else
rv = VPPCOM_EINVAL;
tepap =
vcl_session_tep_attr_get (session, TRANSPORT_ENDPT_ATTR_EXT_ENDPT);
if (!tepap)
{
rv = VPPCOM_EINVAL;
break;
}
vcl_ip_copy_to_ep (&tepap->ext_endpt.ip, ep, tepap->ext_endpt.is_ip4);
ep->port = tepap->ext_endpt.port;
*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 *) ep->ip,
ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
clib_net_to_host_u16 (ep->port));
break;
case VPPCOM_ATTR_GET_EXT_ENDPT:
if (PREDICT_FALSE (!buffer || !buflen || (*buflen < sizeof (*ep)) ||
!ep->ip))
{
rv = VPPCOM_EINVAL;
break;
}
tepap =
vcl_session_tep_attr_get (session, TRANSPORT_ENDPT_ATTR_EXT_ENDPT);
if (!tepap)
{
rv = VPPCOM_EINVAL;
break;
}
vcl_ip_copy_to_ep (&tepap->ext_endpt.ip, ep, tepap->ext_endpt.is_ip4);
ep->port = tepap->ext_endpt.port;
break;
case VPPCOM_ATTR_SET_LCL_ADDR:

View File

@ -186,6 +186,7 @@ typedef enum
VPPCOM_ATTR_GET_IP_PKTINFO,
VPPCOM_ATTR_GET_ORIGINAL_DST,
VPPCOM_ATTR_GET_NWRITEQ,
VPPCOM_ATTR_GET_EXT_ENDPT,
} vppcom_attr_op_t;
typedef struct _vcl_poll

View File

@ -396,6 +396,7 @@ typedef struct session_accepted_msg_
transport_endpoint_t lcl;
transport_endpoint_t rmt;
u8 flags;
/* TODO(fcoras) maybe refactor to pass as transport attr */
u32 original_dst_ip4;
u16 original_dst_port;
} __clib_packed session_accepted_msg_t;

View File

@ -259,7 +259,8 @@ typedef enum transport_endpt_attr_flag_
_ (u64, next_output_node, NEXT_OUTPUT_NODE) \
_ (u16, mss, MSS) \
_ (u8, flags, FLAGS) \
_ (u8, cc_algo, CC_ALGO)
_ (u8, cc_algo, CC_ALGO) \
_ (transport_endpoint_t, ext_endpt, EXT_ENDPT)
typedef enum transport_endpt_attr_type_
{