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:

committed by
Dave Wallace

parent
89969288d3
commit
28955ceb8b
@ -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)
|
||||
{
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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_
|
||||
{
|
||||
|
Reference in New Issue
Block a user