diff options
-rw-r--r-- | src/vcl/vcl_private.h | 16 | ||||
-rw-r--r-- | src/vcl/vppcom.c | 98 | ||||
-rw-r--r-- | src/vcl/vppcom.h | 1 | ||||
-rw-r--r-- | src/vnet/session/application_interface.h | 1 | ||||
-rw-r--r-- | src/vnet/session/transport_types.h | 3 |
5 files changed, 96 insertions, 23 deletions
diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h index b89052f96af..0f1a6d24516 100644 --- a/src/vcl/vcl_private.h +++ b/src/vcl/vcl_private.h @@ -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) { diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 2ebb1d8e5b6..1db0a961092 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -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; @@ -989,6 +995,24 @@ vcl_worker_rpc_handler (vcl_worker_t * wrk, void *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) { session_transport_attr_reply_msg_t *mp; @@ -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: diff --git a/src/vcl/vppcom.h b/src/vcl/vppcom.h index 164dc376ad8..a11db951749 100644 --- a/src/vcl/vppcom.h +++ b/src/vcl/vppcom.h @@ -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 diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h index f175e4a58c6..1702a3727de 100644 --- a/src/vnet/session/application_interface.h +++ b/src/vnet/session/application_interface.h @@ -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; diff --git a/src/vnet/session/transport_types.h b/src/vnet/session/transport_types.h index c92cb7939ae..f6058c6cef6 100644 --- a/src/vnet/session/transport_types.h +++ b/src/vnet/session/transport_types.h @@ -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_ { |